C编程-使用sscanff解析文件io字符串
我正在尝试使用C编程语言执行以下操作,如果您能提供帮助或完成代码,我将不胜感激: 我试图用C编程语言编写一个程序,使用文件io,使用sscanf函数解析单词,并输出txt文档(bar.txt)中所有句子中的每个单词。这是说明书 编写一个打开文件bar.txt的程序,将程序命名为“reader”。传递参数以指示要读取的行。根据参数“lines”将文件中的所有行读入缓冲区,并使用sscanf将句子中的所有单词解析为不同的字符串*变量。将每个单词打印到屏幕上,然后返回回车符。您可以硬连线文件名(bar.xt的路径)或使用选项输入文件名 这是我正在使用的txt文件(bar.txt): bar.txtC编程-使用sscanff解析文件io字符串,c,linux,unix,argv,C,Linux,Unix,Argv,我正在尝试使用C编程语言执行以下操作,如果您能提供帮助或完成代码,我将不胜感激: 我试图用C编程语言编写一个程序,使用文件io,使用sscanf函数解析单词,并输出txt文档(bar.txt)中所有句子中的每个单词。这是说明书 编写一个打开文件bar.txt的程序,将程序命名为“reader”。传递参数以指示要读取的行。根据参数“lines”将文件中的所有行读入缓冲区,并使用sscanf将句子中的所有单词解析为不同的字符串*变量。将每个单词打印到屏幕上,然后返回回车符。您可以硬连线文件名(bar
this is the first sentence
this is the 2nd sentence
this is the 3rd sentence
this is the 4th sentence
this is the 5th sentence
文件结尾:bar.txt
this is the first sentence
this is the 2nd sentence
this is the 3rd sentence
this is the 4th sentence
this is the 5th sentence
argv的用法:用法:更新程序[-f“filename”]'行'
-f是可选的(如果未提供,请使用先前程序2(bar.txt)中的硬接线名称)
“lines”是1到10之间的整数(请记住,文件中有来自上一个程序的5-10个字符串)
程序输入的示例输入示例如下:
./reader-f bar.txt 1
输出:
Opening file "bar.txt"
File Sentence 1 word 1 = this
File Sentence 1 word 2 = is
File Sentence 1 word 3 = the
File Sentence 1 word 4 = first
File Sentence 1 word 5 = sentence
File Sentence 5 word 1 = this
File Sentence 5 word 2 = is
File Sentence 5 word 3 = the
File Sentence 5 word 4 = 5th
File Sentence 5 word 5 = sentence
另一个例子
/读卡器-f bar.txt 5
输出:
Opening file "bar.txt"
File Sentence 1 word 1 = this
File Sentence 1 word 2 = is
File Sentence 1 word 3 = the
File Sentence 1 word 4 = first
File Sentence 1 word 5 = sentence
File Sentence 5 word 1 = this
File Sentence 5 word 2 = is
File Sentence 5 word 3 = the
File Sentence 5 word 4 = 5th
File Sentence 5 word 5 = sentence
命令示例:
./reader -f bar.txt 5
./reader -f bar.txt 2
./reader -f bar.txt 7
./reader 2
./reader 5
./reader 8
./reader 11
这是到目前为止我所拥有的代码。请修复代码以显示所需的输出:
#include <stdlib.h>
#include <stdio.h>
#define MAXCHAR 1000
int main(int argc, char *argv[]) {
FILE *file;
char string[MAXCHAR];
char* filename = "c:\\cprogram\\fileio-activity\\bar.txt";
int integer = argv[3][0] - 48;
int i; //for loops
if (argv[1][0] == '-' && argv[1][1] == 'f')
{
file = fopen(filename, "r");
if (file == NULL){
printf("Could not open file %s",filename);
return 1;
}
while (fgets(string, MAXCHAR, file) != NULL)
printf("%s", string);
fclose(file);
return 0;
}
}
#包括
#包括
#定义MAXCHAR 1000
int main(int argc,char*argv[]){
文件*文件;
字符字符串[MAXCHAR];
char*filename=“c:\\cprogram\\fileio activity\\bar.txt”;
int integer=argv[3][0]-48;
int i;//用于循环
如果(argv[1][0]='-'&&argv[1][1]=='f')
{
file=fopen(文件名为“r”);
if(file==NULL){
printf(“无法打开文件%s”,文件名);
返回1;
}
while(fgets(string,MAXCHAR,file)!=NULL)
printf(“%s”,字符串);
fclose(文件);
返回0;
}
}
如果他们使用-f
选项,您需要从argv
获取文件名。您需要根据是否提供了此选项,从不同的参数中获取行数
使用strcmp()
比较字符串,而不是单独测试每个字符。并使用atoi()
将行
参数转换为整数,因为您的方法仅适用于单个数字
#include <stdlib.h>
#include <stdio.h>
#define MAXCHAR 1000
function usage() {
fprintf(stderr, "Usage: reader [-f filename] lines\n");
exit(1);
}
int main(int argc, char *argv[]) {
FILE *file;
char string[MAXCHAR];
char* filename = "c:\\cprogram\\fileio-activity\\bar.txt";
int integer;
int i; //for loops
if (argc < 2) {
usage();
}
# Process arguments
if (strcmp(argv[1], "-f") == 0)
{
if (argc < 4) {
usage();
}
filename = argv[2];
integer = atoi(argv[3]);
} else {
integer = atoi(argc[1]);
}
file = fopen(filename, "r");
if (file == NULL){
fprintf(stderr, "Could not open file %s\n",filename);
return 1;
}
while (fgets(string, MAXCHAR, file) != NULL)
printf("%s", string);
fclose(file);
return 0;
}
#包括
#包括
#定义MAXCHAR 1000
函数用法(){
fprintf(stderr,“用法:读卡器[-f文件名]行\n”);
出口(1);
}
int main(int argc,char*argv[]){
文件*文件;
字符字符串[MAXCHAR];
char*filename=“c:\\cprogram\\fileio activity\\bar.txt”;
整数;
int i;//用于循环
如果(argc<2){
用法();
}
#过程参数
if(strcmp(argv[1],“-f”)==0)
{
如果(argc<4){
用法();
}
filename=argv[2];
整数=atoi(argv[3]);
}否则{
整数=atoi(argc[1]);
}
file=fopen(文件名为“r”);
if(file==NULL){
fprintf(stderr,“无法打开文件%s\n”,文件名);
返回1;
}
while(fgets(string,MAXCHAR,file)!=NULL)
printf(“%s”,字符串);
fclose(文件);
返回0;
}
要添加Barmar已经回答的内容,完成作业的进一步步骤:
将字符串拆分为单独的单词通常称为标记化,我们通常使用它。有几种方法可以用来做这件事。例如:
sscanf(字符串,“%s%s%s”、word1、word2、word3)
处理可能需要的字缓冲区数量。(如果使用例如char word1[100]
,则使用%99s
,以避免缓冲区溢出错误。必须为字符串\0
的结尾保留一个字符)
sscanf()
的返回值告诉您它复制到字缓冲区的字数。但是,如果string
包含的字数超过指定的字数,则多余的字数将丢失
如果练习指定了字符串的最大长度,例如N,那么您知道最多可以有N/2+1个单词,每个单词的最大长度为N,因为每个连续的单词对必须由至少一个空格或其他空白字符分隔。
sscanf(string+off,“%s%n”,word和len)
获取循环中的每个单词。对于每个新词,它将返回1(将int len
设置为正数),并且0
或EOF
当string
从off
开始不包含任何其他单词时
其思想是,对于每个新词,您通过len
递增off
,从而在每次迭代中检查字符串的其余部分。
sscanf(字符串+关闭,“%n%*s%n”,&start,&end)
和int start,end
获取包含下一个单词的位置范围。在通话前设置start=-1
和end=-1
,并在通话后重复end>start
。通过将end
添加到off
前进到下一个单词
下一个单词的开头(当start>=0
时)是string+start
,它有end-start
个字符
要“模拟”strtok()
行为,可以使用例如char saved=string[off+end]临时保存终止字符(可以是空格或字符串结尾字符)
,然后将其替换为字符串结尾字符,string[off+end]='\0'
,因此(string+start)
是指向单词的指针,就像strtok()
返回一样。在n之前