C从std错误读取字符串
我想从标准输入读取字符串并将其输出到控制台。我用的是这种方法:
char* cmdline;
do{
scanf("%s\n", &cmdline);
printf("%s\n", cmdline);
}while(cmdline != "quit");
但这不起作用。我有这个错误分段错误(核心转储)
I want to read string from standart input and output it in on console. I use this way:
char* cmdline;
do{
scanf("%s\n", &cmdline);
printf("%s\n", cmdline);
}while(cmdline != "quit");
But this doesn't work. I have this error Segmentation fault (core dumped)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是一个指针。您没有分配空间来存储字符串。
您应该这样做:
分配动态内存来存储字符串。
否则使用 char 数组而不是指针:
is a pointer. You are not allocating space for storing the string.
You should do:
for allocating dynamic memory for storing the string.
Otherwise use an array of char instead of a pointer:
cmdline
只是一个指针 - 您实际上需要使用malloc
或固定大小的数组为其分配空间。cmdline
is just a pointer -- you need to actually allocate space for it usingmalloc
or a fixed-size array.我发现您的代码存在三个错误:
I spotted three errors with your code:
您已定义
char *cmdline
但未分配cmdline
指针,根据
请先
需要调整字符串长度
n
。编辑1:
在您的版本中,当您使用 cmdline 而不分配它时,实际上 cmdline 包含一个可以是任何值的值,并且使用该值进行内存访问是尝试访问某些内存区域您不知道在哪里,并且在具有内存保护的操作系统(现在的所有操作系统)中不允许这样做。因此,当您在cmdline中存储某些内容时,它将进入无效位置,这是不允许的,操作系统将针对非法内存访问发出分段错误。
使用
malloc
调用从操作系统(堆)分配内存后,cmdline
将包含一个值,该值将具有操作系统发布的内存位置地址您的代码是为您保留的,您有权在其中写入。因此,使用变量引用该位置会产生正确的内存引用,您可以像平常一样使用它。另请注意,如果您尝试超出分配的内存块,即访问超出第 n 个位置(如果您已分配 n 个字节),那么您也可能会遇到段错误,因为超出该限制的内存位置不会为您注册/分配。虽然在这种情况下您可能不会遇到段错误,但在这样的位置写入可能是不可预见的。尝试详细说明这一点的唯一原因是,定义 char * 而不分配它在代码中使用它是一种非常常见的弊端,因为旧的 Turbo C++ 3.1 不会抱怨,这是被很多人使用。然后他们打电话给我,告诉我 GCC 编译器坏了,因为代码无法在其中运行,而在 TC++ 3.1 中运行完美。
编辑2:
或者简单地使用静态数组
,其中
MAX_SIZE
根据您的需要设置EDIT3:天哪,
您已经完成了
cmdline != "quit"
这永远不会工作。解决方案就在您的代码中。这会将
cmdline
字符串与静态字符串“quit”逐个匹配。您的解决方案将永远无法工作,因为当您执行
cmdline != "quit"
时,只需两个地址正在被比较。首先,cmdline
表示您通过malloc
调用分配的地址,第二个是位于可执行文件数据部分内的字符串“quit”的地址,或者简单地说在加载程序的内存中的某个区域中,您不知道。比较这两个值不会比较这些地址的内容,即不会比较其中的字符串。编辑4:
另外
scanf ("%s", &cmdline);
也是不正确的,因为cmdline
本身代表了要存储字符串的位置的地址。正确的代码是:You have defined
char *cmdline
but not allocated thecmdline
pointerdo
first
Adjust the string length
n
as per your need.EDIT1:
In your version when you use
cmdline
without allocation it, then actuallycmdline
contains a value which can be anything, and using that for memory access is an attempt to access some memory area which you do not know where and is not permitted in OSes with memory protection (all the OSes nowadays). So when you store something incmdline
it will go in an invalid location, which is not permitted and the OS will issue segmentation fault for illegal memory access.After you have allocated the memory from the OS (heap) with the
malloc
call thecmdline
will contain a value which will have a memory location address which was issued by the OS for your code and is reserved for you, in which you have permission to write. So referring the location with the variable makes a proper memory reference and you can you it as normal. Also note if you try to go beyond the allocated memory block, ie access beyond then
th location (if you have allocatedn
bytes), then you can also get a segfault, as the memory locations beyond that limit is not registered/allocated for you. Although you might not get a segfault in this case, but writing in such location can be unpredective.The sole cause for an attempt to elaborate this is that this is a very common malpractice to define a
char *
and without allocating it use it in codes, because the old Turbo C++ 3.1 does not complain, which is used by a LOT of people out there. Then they call me and tell that the GCC compiler is broken as the code does not run in it and runs perfect in TC++ 3.1.EDIT2:
Or simply use static array
where
MAX_SIZE
is set as per your needEDIT3: OMG
You have done
cmdline != "quit"
this will never work. The solution isin your code. This will match the
cmdline
string character by character with the static string "quit"Your solution will never work because when you do
cmdline != "quit"
then simply two addresses are being compared. First, thecmdline
represents the address which you allocated with themalloc
call, Second the address of the string "quit" which lies inside the data section of the executable, or simply in some area inside the memory where your program is loaded, which you have no idea. Comparing these two values will not compare the contents of these addresses, ie will not compare the strings inside it.EDIT4:
Also
scanf ("%s", &cmdline);
is incorrect ascmdline
itself represents the address of the location where you want to store the string. The correct code is: