fscanf() 如何进入下一行?
fscanf() how to go in the next line?
所以我在一个文件中有一大堆文本,我需要识别 $ 符号之间的一些单词并将它们称为数字,然后在另一个文件中打印修改后的文本以及数字对应的内容。
行也没有定义,列最多 80 个字符。
例如:
I $like$ cats.
I [1] cats.
[1] --> like
我就是这么做的:
#include <stdio.h>
#include <stdlib.h>
#define N 80
#define MAX 9999
int main()
{
FILE *fp;
int i=0,count=0;
char matr[MAX][N];
if((fp = fopen("text.txt","r")) == NULL){
printf("Error.");
exit(EXIT_FAILURE);
}
while((fscanf(fp,"%s",matr[i])) != EOF){
printf("%s ",matr[i]);
if(matr[i] == '[=11=]')
printf("\n");
//I was thinking maybe to find two $ but Idk how to replace the entire word
/*
if(matr[i] == '$')
count++;
if(count == 2){
...code...
}
*/
i++;
}
fclose(fp);
return 0;
}
我的问题是 fscanf 无法识别 '[=12=]'
,所以当我打印数组时它不会进入下一行。我也不知道如何替换 $word$
有一个数字。
使用 fread() 将文件内容读取到 char[] 缓冲区。然后遍历这个缓冲区,每当你找到一个 $ 你执行一个 strncmp 来检测用哪个值替换它(记住,在单词的末尾有第二个 $)。要用数字替换 $word$,您需要缩小或扩展单词位置的缓冲区 - 这取决于 ascii 格式数字的字符串大小(在 google 上查找解决方案,通常你应该能够使用 memmove)。然后你可以将数字写入洞穴,这是由于扩展缓冲区而产生的(也只是覆盖 $word$ )。
然后将缓冲区写入文件,覆盖其之前的所有内容。
在 select 情况下,fscanf()
是否识别“\0”,但这不是这里的问题。
代码需要检测'\n'
。 fscanf(fp,"%s"...
不会那样做。 "%s"
指示的第一件事是消耗(而不是保存)任何领先的白色-space,包括 '\n'
。使用 fgets()
.
读取一行文本
一次简单地读取 1 行。然后沿着缓冲区前进寻找单词。
以下使用 "%n"
跟踪缓冲区扫描停止的距离。
// more room for \n [=10=]
#define BUF_SIZE (N + 1 + 1)
char buffer[BUF_SIZE];
while (fgets(buffer, sizeof buffer, stdin) != NULL) {
char *p = buffer;
char word[sizeof buffer];
int n;
while (sscanf(p, "%s%n", word, &n) == 1) {
// do something with word
if (strcmp(word, "$zero$") == 0) fputs("0", stdout);
else if (strcmp(word, "$one$") == 0) fputs("1", stdout);
else fputs(word, stdout);
fputc(' ', stdout);
p += n;
}
fputc('\n', stdout);
}
fscanf("%s")
不仅会一次读取一个以空格分隔的字符串,还会吃掉这些字符串之间的所有空格,包括行终止符。如果你想在输出中重现输入空白,正如你的例子所建议的那样,那么你需要一种不同的方法。
Also lines are not defined and columns should be max 80 characters.
我认为这意味着 number 行是事先不知道的,可以假设没有一行包含超过 80 个字符(不算任何行终止符)。
当你说
My problem is that fscanf doesn't recognize '[=25=]' so it doesn't go in the next line when I print the array
我猜你说的是这段代码:
char matr[MAX][N];
/* ... */
if(matr[i] == '[=10=]')
鉴于 matr
的声明,给定的条件将 总是 评估为 false
,而不管任何其他考虑。 fscanf()
根本不考虑。 matr[i]
的类型是 char[N]
,类型为 char
的 N
个元素的数组。计算结果为指向数组第一个元素的指针,该指针永远不会是 NULL
。看起来您正在尝试确定何时编写换行符,但与此方法类似的任何方法都无法做到这一点。
我建议您首先采纳@Barmar 的建议,通过 fgets()
逐行阅读。可能看起来像这样:
char line[N+2]; /* N + 2 leaves space for both newline and string terminator */
if (fgets(line, sizeof(line), fp) != NULL) {
/* one line read; handle it ... */
} else {
/* handle end-of-file or I/O error */
}
然后对于你阅读的每一行,用你喜欢的任何方式解析出 "$word$"
标记,并输出所需的结果(除了 $
分隔的标记之外的所有内容;括号替换编号对于每个令牌)。当然,您需要记住替换标记以供以后输出。记得制作 副本 ,因为缓冲区将在每次读取时被覆盖(如果按照我上面的建议完成)。
所以我在一个文件中有一大堆文本,我需要识别 $ 符号之间的一些单词并将它们称为数字,然后在另一个文件中打印修改后的文本以及数字对应的内容。 行也没有定义,列最多 80 个字符。
例如:
I $like$ cats.
I [1] cats.
[1] --> like
我就是这么做的:
#include <stdio.h>
#include <stdlib.h>
#define N 80
#define MAX 9999
int main()
{
FILE *fp;
int i=0,count=0;
char matr[MAX][N];
if((fp = fopen("text.txt","r")) == NULL){
printf("Error.");
exit(EXIT_FAILURE);
}
while((fscanf(fp,"%s",matr[i])) != EOF){
printf("%s ",matr[i]);
if(matr[i] == '[=11=]')
printf("\n");
//I was thinking maybe to find two $ but Idk how to replace the entire word
/*
if(matr[i] == '$')
count++;
if(count == 2){
...code...
}
*/
i++;
}
fclose(fp);
return 0;
}
我的问题是 fscanf 无法识别 '[=12=]'
,所以当我打印数组时它不会进入下一行。我也不知道如何替换 $word$
有一个数字。
使用 fread() 将文件内容读取到 char[] 缓冲区。然后遍历这个缓冲区,每当你找到一个 $ 你执行一个 strncmp 来检测用哪个值替换它(记住,在单词的末尾有第二个 $)。要用数字替换 $word$,您需要缩小或扩展单词位置的缓冲区 - 这取决于 ascii 格式数字的字符串大小(在 google 上查找解决方案,通常你应该能够使用 memmove)。然后你可以将数字写入洞穴,这是由于扩展缓冲区而产生的(也只是覆盖 $word$ )。 然后将缓冲区写入文件,覆盖其之前的所有内容。
fscanf()
是否识别“\0”,但这不是这里的问题。
代码需要检测'\n'
。 fscanf(fp,"%s"...
不会那样做。 "%s"
指示的第一件事是消耗(而不是保存)任何领先的白色-space,包括 '\n'
。使用 fgets()
.
一次简单地读取 1 行。然后沿着缓冲区前进寻找单词。
以下使用 "%n"
跟踪缓冲区扫描停止的距离。
// more room for \n [=10=]
#define BUF_SIZE (N + 1 + 1)
char buffer[BUF_SIZE];
while (fgets(buffer, sizeof buffer, stdin) != NULL) {
char *p = buffer;
char word[sizeof buffer];
int n;
while (sscanf(p, "%s%n", word, &n) == 1) {
// do something with word
if (strcmp(word, "$zero$") == 0) fputs("0", stdout);
else if (strcmp(word, "$one$") == 0) fputs("1", stdout);
else fputs(word, stdout);
fputc(' ', stdout);
p += n;
}
fputc('\n', stdout);
}
fscanf("%s")
不仅会一次读取一个以空格分隔的字符串,还会吃掉这些字符串之间的所有空格,包括行终止符。如果你想在输出中重现输入空白,正如你的例子所建议的那样,那么你需要一种不同的方法。
Also lines are not defined and columns should be max 80 characters.
我认为这意味着 number 行是事先不知道的,可以假设没有一行包含超过 80 个字符(不算任何行终止符)。
当你说
My problem is that fscanf doesn't recognize '[=25=]' so it doesn't go in the next line when I print the array
我猜你说的是这段代码:
char matr[MAX][N]; /* ... */ if(matr[i] == '[=10=]')
鉴于 matr
的声明,给定的条件将 总是 评估为 false
,而不管任何其他考虑。 fscanf()
根本不考虑。 matr[i]
的类型是 char[N]
,类型为 char
的 N
个元素的数组。计算结果为指向数组第一个元素的指针,该指针永远不会是 NULL
。看起来您正在尝试确定何时编写换行符,但与此方法类似的任何方法都无法做到这一点。
我建议您首先采纳@Barmar 的建议,通过 fgets()
逐行阅读。可能看起来像这样:
char line[N+2]; /* N + 2 leaves space for both newline and string terminator */
if (fgets(line, sizeof(line), fp) != NULL) {
/* one line read; handle it ... */
} else {
/* handle end-of-file or I/O error */
}
然后对于你阅读的每一行,用你喜欢的任何方式解析出 "$word$"
标记,并输出所需的结果(除了 $
分隔的标记之外的所有内容;括号替换编号对于每个令牌)。当然,您需要记住替换标记以供以后输出。记得制作 副本 ,因为缓冲区将在每次读取时被覆盖(如果按照我上面的建议完成)。