C从std错误读取字符串

发布于 2024-11-07 00:32:05 字数 218 浏览 0 评论 0原文

我想从标准输入读取字符串并将其输出到控制台。我用的是这种方法:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

内心激荡 2024-11-14 00:32:05
char* cmdline

是一个指针。您没有分配空间来存储字符串。
您应该这样做:

cmdline = malloc(size_of_string);

分配动态内存来存储字符串。
否则使用 char 数组而不是指针:

char cmdline[size_of_string];
char* cmdline

is a pointer. You are not allocating space for storing the string.
You should do:

cmdline = malloc(size_of_string);

for allocating dynamic memory for storing the string.
Otherwise use an array of char instead of a pointer:

char cmdline[size_of_string];
壹場煙雨 2024-11-14 00:32:05

cmdline 只是一个指针 - 您实际上需要使用 malloc 或固定大小的数组为其分配空间。

cmdline is just a pointer -- you need to actually allocate space for it using malloc or a fixed-size array.

病毒体 2024-11-14 00:32:05
char cmdline[80];

do {
    scanf("%79s\n", cmdline);
    printf("%s\n", cmdline);
} while(strcmp(cmdline, "quit"));

我发现您的代码存在三个错误:

  1. 未为输入缓冲区分配内存
  2. 未将缓冲区传递给 scanf
  3. 未使用 strcmp 比较字符串
char cmdline[80];

do {
    scanf("%79s\n", cmdline);
    printf("%s\n", cmdline);
} while(strcmp(cmdline, "quit"));

I spotted three errors with your code:

  1. Not allocating memory for the input buffer
  2. Not passing a buffer to scanf
  3. Not using strcmp to compare strings
刘备忘录 2024-11-14 00:32:05

您已定义 char *cmdline 但未分配 cmdline 指针,

根据

cmdline = malloc (sizeof (char) * n);

请先

需要调整字符串长度 n

编辑1:
在您的版本中,当您使用 cmdline 而不分配它时,实际上 cmdline 包含一个可以是任何值的值,并且使用该值进行内存访问是尝试访问某些内存区域您不知道在哪里,并且在具有内存保护的操作系统(现在的所有操作系统)中不允许这样做。因此,当您在cmdline中存储某些内容时,它将进入无效位置,这是不允许的,操作系统将针对非法内存访问发出分段错误。

使用 malloc 调用从操作系统(堆)分配内存后,cmdline 将包含一个值,该值将具有操作系统发布的内存位置地址您的代码是为您保留的,您有权在其中写入。因此,使用变量引用该位置会产生正确的内存引用,您可以像平常一样使用它。另请注意,如果您尝试超出分配的内存块,即访问超出第 n 个位置(如果您已分配 n 个字节),那么您也可能会遇到段错误,因为超出该限制的内存位置不会为您注册/分配。虽然在这种情况下您可能不会遇到段错误,但在这样的位置写入可能是不可预见的。

尝试详细说明这一点的唯一原因是,定义 char * 而不分配它在代码中使用它是一种非常常见的弊端,因为旧的 Turbo C++ 3.1 不会抱怨,这是被很多人使用。然后他们打电话给我,告诉我 GCC 编译器坏了,因为代码无法在其中运行,而在 TC++ 3.1 中运行完美。

编辑2:
或者简单地使用静态数组

char cmdline[MAX_SIZE];

,其中 MAX_SIZE 根据您的需要设置

EDIT3:天哪,

您已经完成了 cmdline != "quit" 这永远不会工作。解决方案就

while (strcmp (cmdline, "quit") != 0);

在您的代码中。这会将 cmdline 字符串与静态字符串“quit”逐个匹配。

您的解决方案将永远无法工作,因为当您执行 cmdline != "quit" 时,只需两个地址正在被比较。首先,cmdline 表示您通过 malloc 调用分配的地址,第二个是位于可执行文件数据部分内的字符串“quit”的地址,或者简单地说在加载程序的内存中的某个区域中,您不知道。比较这两个值不会比较这些地址的内容,即不会比较其中的字符串。

编辑4:
另外 scanf ("%s", &cmdline); 也是不正确的,因为 cmdline 本身代表了要存储字符串的位置的地址。正确的代码是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void)
{
  char *cmdline;
  cmdline = malloc (sizeof (char) * 128);       /* or whatever size */
  do
    {
      scanf ("%s", cmdline);
      printf ("%s\n", cmdline);
    }
  while (strcmp (cmdline, "quit") != 0);
  return 0;
}

You have defined char *cmdline but not allocated the cmdline pointer

do

cmdline = malloc (sizeof (char) * n);

first

Adjust the string length n as per your need.

EDIT1:
In your version when you use cmdline without allocation it, then actually cmdline 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 in cmdline 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 the cmdline 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 the n th location (if you have allocated n 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

char cmdline[MAX_SIZE];

where MAX_SIZE is set as per your need

EDIT3: OMG

You have done cmdline != "quit" this will never work. The solution is

while (strcmp (cmdline, "quit") != 0);

in 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, the cmdline represents the address which you allocated with the malloc 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 as cmdline itself represents the address of the location where you want to store the string. The correct code is:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void)
{
  char *cmdline;
  cmdline = malloc (sizeof (char) * 128);       /* or whatever size */
  do
    {
      scanf ("%s", cmdline);
      printf ("%s\n", cmdline);
    }
  while (strcmp (cmdline, "quit") != 0);
  return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文