-1

我得到了这条线:

fscanf(file, "%s %[^\t\n]", message);

现在,当它扫描时,我得到所有字符,直到空格,但我希望它读取到行尾,而不是只读到空格。

4

2 回答 2

1

目前还不完全清楚你在追求什么。如果您希望行中的所有数据都到换行符(并且您希望读取换行符),那么使用最简单fgets()

if (fgets(message, sizeof(message), file) != 0)
{
    size_t len = strlen(message);
    if (message[len-1] == '\n')
        message[len-1] = '\0';
    else
        ...line was too long to fit in message...
    ...use message...
}

如果您必须使用fscanf(),那么您可以使用:

char message[256];

if (fscanf(file, "%255[^\n]", message) == 1)
{
    int c;
    while ((c = getc(file)) != EOF && c != '\n')
        ;    // Ignore characters to newline
    ...use message...
}

在您的版本中,您有(至少)三个问题:

fscanf(file, "%s %[^\t\n]", message);
  1. 您必须转换分配的规范,但您只提供一个变量。
  2. 您不检查 from 的返回值fscanf(),因此您不知道它是否有效。
  3. 您的格式字符串没有按照您的想法执行。

前两个问题相当直截了当。最后一个不是。-family 格式字符串中的空格scanf()表示任意的空白序列(扫描集中除外)。因此,格式字符串中的空格将读取空格(空格、制表符、换行符等),直到输入中的某些内容与空格不匹配。这意味着用于多种用途的字母、数字或标点符号。然后将一系列此类字符读入您在修复问题 1 时提供的变量中。

#include <stdio.h>

int main(void)
{
  char msg1[256];
  char msg2[256];
  int  n;

  if ((n = scanf("%s %[^\t\n]", msg1, msg2)) == 2)
    printf("1: <<%s>>\n2: <<%s>>\n", msg1, msg2);
  else
    printf("Oops: %d\n", n);
  return 0;
}

样品运行:

$ ./scan
abracadabra


          widgets
1: <<abracadabra>>
2: <<sigets>>
$

如果您想阅读 中的换行符(或制表符)message,那么您需要:

if (fscanf(file, "%[^\t\n]", message) != 1)
    ...oops...
else
    ...use message...
于 2013-06-24T23:00:05.437 回答
-1

在 C 中读取 C 字符串时,您应该使用 gets 系列而不是 scanf 系列

char * gets ( char * str );

http://www.cplusplus.com/reference/cstdio/gets/?kw=gets

char * fgets ( char * str, int num, FILE * stream );

http://www.cplusplus.com/reference/cstdio/fgets/

这些读取直到找到 EOL 字符或达到一定的字符限制(为了不发生缓冲区溢出)

编辑

这是逐行读取整个文件的方法

while ( fgets ( line, size_of_buffer , file ) != NULL ){ /* read a line */
     fputs ( line, stdout ); /* write the line */
}

while 循环中的条件确保文件没有结束。

正如评论中所说,gets 是一个非常危险的功能,不应使用。

于 2013-06-24T20:52:34.977 回答