简体   繁体   English

包含比指定更多字符的数组

[英]Array containing more characters than specified

I am learning file management in C. I wrote this code and the output wasn't what I expected. 我正在学习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;
}

I compiled it and ran it as follows 我编译并按如下方式运行

gcc test.c
a abcdefghijklmnopqrstuvwxyz

The output was as follows: 输出如下:

abcdefghijklmnopqrstuvwxyz

I thought it would output only first 12 letters. 我认为它只会输出前12个字母。

Where did I go wrong in my thought process? 我在思考过程中哪里出错了?

fscanf(fp,"%[^\\n]", str); attempts to read characters and writes them to memory, starting at str , until '\\n' or EOF is encountered, regardless of the length of str 尝试读取字符并将其写入内存,从str开始,直到遇到'\\ n'或EOF,而不管str的长度如何

So, with 因此,

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

reading the string of 27 characters "abcdefghijklmnopqrstuvwxyz " from the file writes 28 characters from &str[0] and has an unspecified behavior (probably a crash). 从文件中读取27个字符的字符串“ abcdefghijklmnopqrstuvwxyz”会从&str [0]中写入28个字符,并且行为未指定(可能是崩溃)。

Array containing more characters than specified 包含比指定更多字符的数组

no, str[12] allows to store 11 characters more the null ending character, nothing more. 不, str[12]允许多存储11个字符的空结束字符,仅此而已。

To read at most 11 characters from the file do : 要从文件中读取最多11个字符,请执行以下操作:

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

Doing that, compilation and execution : 这样做,编译和执行:

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

and under valgrind : 和在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)

PS add a \\n in the printf printf("%s\\n", str); PS在printf printf("%s\\n", str);添加\\ n printf("%s\\n", str); of use puts to have a more readable result : 利用有一个更可读的结果:

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

PS of course to read 12 characters from the file do PS当然要从文件中读取12个字符

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

Even though you allocated an array of size 12 this doesn't mean you cannot write (or read) beyond its boundaries. 即使您分配了大小为12的数组,这也不意味着您无法超出其边界写入(或读取)。

fscanf expects a pointer as third argument and pointer have no information regarding length as such fscanf cannot know how much memory you allocated, this is the reponsability of the caller. fscanf希望将指针作为第三个参数,并且指针没有有关长度的信息,因为fscanf无法知道您分配了多少内存,这是调用方的责任。

C is very liberal when it comes to accessing memory ;) 在访问内存时,C非常自由;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM