[英]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.