【问题标题】:Reading data in C在 C 中读取数据
【发布时间】:2015-11-02 19:54:47
【问题描述】:

所以我的文件有 full_file_path # 形式的数据,例如,

C:/dev/Java/src/java/util/concurrent/ConcurrentHashMap.java 212
C:/dev/Java/src/java/util/HashMap.java 212
C:/dev/Java/src/java/lang/CharacterData02.java 190
C:/dev/Java/src/java/lang/CharacterData0E.java 190
C:/dev/Java/src/java/nio/DirectCharBufferS.java 123
C:/dev/Java/src/java/nio/DirectCharBufferU.java 123
...

我正在尝试读取文件

int dup;
char file[MAX_LINE];
...
FILE *fp;
fp = fopen("OUTPUT100.txt", "r");
while (fscanf(fp, "%s %d\n", &file, &dup) == 1) {
   printf("%s %d\n", file, dup);
}
fclose(fp);

但是输出很垃圾

   has 0 duplciate lines of code
  RJ9 has 0 duplciate lines of code
   has 0 duplciate lines of code
  ▒▒" has 0 duplciate lines of code
   has 0 duplciate lines of code
  "A▒ has 0 duplciate lines of code
   has 0 duplciate lines of code
  7▒cw has 0 duplciate lines of code
   has 0 duplciate lines of code
   has 0 duplciate lines of code

我做错了什么?

编辑:我的“仍然吐出垃圾”的 cmets 只是脑放屁。我在吐出垃圾的while循环下方的循环中有一个printf。向上滚动几百行后,我开始看到有意义的数据。注释掉 printf 会产生预期的结果。工作读取使用while (fscanf(fp, "%s %d\n", file, &dup) == 2)。谢谢大家。

【问题讨论】:

  • while (fscanf(fp, "%s %d\n", file, &dup) == 1) No & before file 它已经是一个指针。
  • @DavidC.Rankin,它仍然吐出垃圾。
  • while (fscanf(fp, "%s %d\n", file, &dup) == 2)(很抱歉你的匹配数也被取消了)
  • 在调用`fopen()时,总是检查(!=NULL)返回值以保证操作成功
  • 头文件:unistd.h 公开了众所周知的函数:dup()。发布的代码不符合 small, cleanly compiles, has example of the problem 的 stackoverflow 标准,因此,除其他外,未知 dup() 函数是否暴露。

标签: c file scanf


【解决方案1】:

像这样修改你的循环调用

while (fscanf(fp, "%s %d\n", file, &dup) == 2) {

正如@mjswartz 所说,file 是一个数组,当您将其传递给fscanf 时,它会衰减为char*。此外,fscanf 将返回它设法检索的参数数量,并且您每行扫描 2 个变量。

【讨论】:

  • 刚刚用你的文件测试了你的代码,它扫描得很好。这条消息“有 0 行重复的代码”是从哪里打印出来的? “OUTPUT100.txt”中是否有任何文件名中带有空格的文件?
【解决方案2】:

好吧,fscanf 返回成功格式说明符的数量,因此它会在成功时返回 2,并且您正在检查它是否返回 1。您可能想要检查 EOF 字符并停止从那里读取.

另外,file 变量是一个可以用作指针的数组,因此您不应该尝试引用它。

while (1)
{
    r = fscanf(fp, "%s %d\n", file, &dup);
    if( r == EOF ) 
       break;
    printf("%s %d\n", file, dup);
}

【讨论】:

  • C& 在数组名之前不是也给出了数组的地址吗?即file&file 是相同的值(但类型不同)。
  • @kaylum 后者将是一个指向冗余指针的指针。
  • @Linus。不是,不是。它将是一个指向数组类型的指针。在C 中,数组与指针不同(尽管在许多情况下可以像指针一样使用)。这是一种常见的误解(尽管通常不会产生影响)。
  • @kaylum 你是对的,我没有意识到他使用了这样一个带有字符串常量的数组,但是没有必要将指向数组的指针传递给fscanf。跨度>
【解决方案3】:

关于这一行:

while (fscanf(fp, "%s %d\n", &file, &dup) == 1) {

fscanf() 返回成功输入/转换的次数

I.E.如果成功,且格式字符串有2个转换参数,则返回2,而不是1。

请阅读/理解fscanf() 的手册页

格式字符串不应有尾随 '\n'(不像 printf() 几乎总是有尾随 '\n')

要使用任何“剩余”空白,例如换行符,请在格式字符串中放置一个前导空格。

当前格式说明符“%s”没有最大长度修饰符,因此输入文件中的数据可能会超出可用的输入缓冲区,从而导致未定义的行为,从而导致段错误事件。

注意:在C语言中,数组名降级为指向数组第一个字节的指针,所以不要取数组的地址:file

建议:

while (fscanf(fp, " %#s %d\n", file, &dup) == 2) { 

其中# 是值 MAX_LINE-1。

发布的代码绝对不可能输出作为输出发布的文本。

建议贴出实际代码、实际输出和预期输出。

注意:file 是 char 数组的一个糟糕名称。建议一些有意义的东西,比如buffer

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 2019-09-22
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 2018-03-17
    相关资源
    最近更新 更多