c - 包含多于指定字符的数组

标签 c file

我正在学习用 C 语言进行文件管理。我编写了这段代码,但输出结果与我预期的不同。

#include <stdio.h>

int main(int argc, char * argv[]){
    int i;
    char str[12];
    FILE *fp;
    fp = fopen("Names.dat", "w+");
    for(i = 1; i < argc; i++){
         fprintf(fp, "%s ", argv[i]);
    }
    rewind(fp);
    fscanf(fp,"%[^\n]", str);
    printf("%s", str);
    return 0;
}

我编译运行如下

gcc test.c
a abcdefghijklmnopqrstuvwxyz

输出如下:

abcdefghijklmnopqrstuvwxyz

我以为它只会输出前 12 个字母。

我的思维过程哪里出了问题?

最佳答案

fscanf(fp,"%[^\n]", str); 尝试读取字符并将它们写入内存,从 str 开始,直到 '\无论 str

的长度如何,遇到 n' 或 EOF

所以,用

char str[12];
...
fscanf(fp,"%[^\n]", str);

从文件中读取 27 个字符的字符串“abcdefghijklmnopqrstuvwxyz”会从 &str[0] 中写入 28 个字符,并且具有未指定的行为(可能是崩溃)。

Array containing more characters than specified

不,str[12] 允许存储 11 个以上的空结尾字符,仅此而已。

要从文件中读取最多 11 个字符,请执行以下操作:

fscanf(fp,"%11[^\n]", str);

这样做,编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra m.c
pi@raspberrypi:/tmp $ ./a.out abcdefghijklmnopqrstuvwxyz
abcdefghijkpi@raspberrypi:/tmp $ 

valgrind 下:

pi@raspberrypi:/tmp $ valgrind ./a.out abcdefghijklmnopqrstuvwxyz
==10408== Memcheck, a memory error detector
==10408== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10408== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==10408== Command: ./a.out abcdefghijklmnopqrstuvwxyz
==10408== 
abcdefghijk==10408== 
==10408== HEAP SUMMARY:
==10408==     in use at exit: 352 bytes in 1 blocks
==10408==   total heap usage: 3 allocs, 2 frees, 5,472 bytes allocated
==10408== 
==10408== LEAK SUMMARY:
==10408==    definitely lost: 0 bytes in 0 blocks
==10408==    indirectly lost: 0 bytes in 0 blocks
==10408==      possibly lost: 0 bytes in 0 blocks
==10408==    still reachable: 352 bytes in 1 blocks
==10408==         suppressed: 0 bytes in 0 blocks
==10408== Rerun with --leak-check=full to see details of leaked memory
==10408== 
==10408== For counts of detected and suppressed errors, rerun with: -v
==10408== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

附言在使用 puts 的 printf printf("%s\n", str); 中添加一个\n 以获得更具可读性的结果:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra m.c
pi@raspberrypi:/tmp $ ./a.out abcdefghijklmnopqrstuvwxyz
abcdefghijk
pi@raspberrypi:/tmp $ 

附言当然要从文件中读取 12 个字符

char str[13];
...
fscanf(fp,"%12[^\n]", str);

关于c - 包含多于指定字符的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54969277/

相关文章:

C使用函数参数返回值

c - 函数存储在内存中的什么位置?

c++ - 在 C++ 中创建动态文件指针

C 列表的列表

c - 如何用 C 将二进制位写入二进制文件?

c - If 语句比较开销与赋值开销

C程序栈

image - flutter 如何将 Assets 中的图片保存到内部存储?

android - 从自己的声音文件语音到文本

java - 静态检查文件是否存在