这两种方法在C中获取字符串输入的区别是什么?

时间:2021-05-19 21:28:25

I'm learning C programming and I have to implement a program that read an input string of of unknown size. I wrote this code:

我正在学习C编程,我必须实现一个程序来读取未知大小的输入字符串。我写的这段代码:

int main() {
    char *string;
    char c;
    int size = 1;

    string = (char*)malloc(sizeof(char));

    if (string == NULL) {
        printf("Error.\n");
        return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != '\n') {
        *string = c;
        string = (char*)realloc(string, sizeof(char) * (size + 1));
        size++;
    }
    string[size - 1] = '\0';

    printf("Input string: %s\n", string);

    free(string);
    return 0;
}

But the last printf doesn't show the whole string but only the last char. So if I enter hello, world the last printf prints d.

但是最后的printf没有显示整个字符串,只有最后一个字符。如果我输入hello,最后一个printf打印d。

After a little research I tried this code and it works! But I don't get the difference with mine.

在做了一些研究之后,我尝试了这个代码,它确实有效!但是我和我的不一样。

I hope I made myself clear, thank you for your attention.

我希望我讲的很清楚,谢谢大家的关注。

4 个解决方案

#1


3  

There are several problems with your code:

你的代码有几个问题:

  • you store all characters into the first byte of allocated memory
  • 将所有字符存储到分配内存的第一个字节中
  • you read characters into a char variable, you cannot correctly test for EOF.
  • 将字符读入char变量中,不能正确地测试EOF。
  • you will run an infinite loop, allocating all available memory and finally crash if standard input does not contain a '\n', such as redirecting from an empty file.
  • 您将运行一个无限循环,分配所有可用内存,如果标准输入不包含“\n”,例如从空文件重定向,则最终崩溃。
  • less important, you reallocate the buffer for each byte read, inefficient but can be optimized later.
  • 不太重要的是,您可以重新分配每个字节读取的缓冲区,效率不高,但是可以稍后进行优化。

Here is a corrected version:

这里有一个修正版:

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

int main() {
    char *string;
    int c;
    int len = 0;

    string = malloc(1);
    if (string == NULL) {
         printf("Error.\n");
         return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != EOF && c != '\n') {
        string[len++] = c;
        string = realloc(string, len + 1);
        if (string == NULL) {
            printf("cannot allocate %d bytes\n", len + 1);
            return -1;
        }
    }
    string[len] = '\0';

    printf("Input string: %s\n", string);
    free(string);
    return 0;
}

Regarding your question about the difference with the linked code, it uses the same method, has one less bug but also one more bug:

关于你关于链接代码的区别的问题,它使用了相同的方法,有一个bug少了一个bug,但也多了一个bug:

  • it stores the character in the appropriate offset in str.
  • 它将字符存储在str中适当的偏移量中。
  • it runs an infinite loop if the input file does not contain a '\n', same as yours.
  • 如果输入文件不包含“\n”,则运行一个无限循环。
  • it invokes undefined behavior because c is not initialized for first test.
  • 它调用未定义的行为,因为c没有为第一次测试初始化。

#2


5  

In your version of the code you assign the newly read character, c, to string, using:

在您的代码版本中,您将新读取的字符c分配给string,使用:

*string = c;

*string points at the beginning of the string so you keep replacing the first character of string with the newly read character.

*字符串点在字符串的开头,所以您要不断地用新读的字符替换字符串的第一个字符。

The code you linked to does the following:

您所链接的代码如下:

str[i] = c

Basically, it is assigning the character to the end of the string, using the index i.

基本上,它使用索引i将字符分配到字符串的末尾。

In your version of the code you could use size - 1 instead of i.

在您的版本的代码中,您可以使用size - 1而不是i。

#3


3  

Try changing:

试着改变:

*string = c;

To:

:

string[size-1] = c;

That way you won't just overwrite the first character each time.

这样就不会每次都覆盖第一个字符。

#4


1  

try

试一试

*(string + size - 1) = c;

maybe this helps

也许这可以帮助

#1


3  

There are several problems with your code:

你的代码有几个问题:

  • you store all characters into the first byte of allocated memory
  • 将所有字符存储到分配内存的第一个字节中
  • you read characters into a char variable, you cannot correctly test for EOF.
  • 将字符读入char变量中,不能正确地测试EOF。
  • you will run an infinite loop, allocating all available memory and finally crash if standard input does not contain a '\n', such as redirecting from an empty file.
  • 您将运行一个无限循环,分配所有可用内存,如果标准输入不包含“\n”,例如从空文件重定向,则最终崩溃。
  • less important, you reallocate the buffer for each byte read, inefficient but can be optimized later.
  • 不太重要的是,您可以重新分配每个字节读取的缓冲区,效率不高,但是可以稍后进行优化。

Here is a corrected version:

这里有一个修正版:

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

int main() {
    char *string;
    int c;
    int len = 0;

    string = malloc(1);
    if (string == NULL) {
         printf("Error.\n");
         return -1;
    }
    printf("Enter a string:");
    while ((c = getchar()) != EOF && c != '\n') {
        string[len++] = c;
        string = realloc(string, len + 1);
        if (string == NULL) {
            printf("cannot allocate %d bytes\n", len + 1);
            return -1;
        }
    }
    string[len] = '\0';

    printf("Input string: %s\n", string);
    free(string);
    return 0;
}

Regarding your question about the difference with the linked code, it uses the same method, has one less bug but also one more bug:

关于你关于链接代码的区别的问题,它使用了相同的方法,有一个bug少了一个bug,但也多了一个bug:

  • it stores the character in the appropriate offset in str.
  • 它将字符存储在str中适当的偏移量中。
  • it runs an infinite loop if the input file does not contain a '\n', same as yours.
  • 如果输入文件不包含“\n”,则运行一个无限循环。
  • it invokes undefined behavior because c is not initialized for first test.
  • 它调用未定义的行为,因为c没有为第一次测试初始化。

#2


5  

In your version of the code you assign the newly read character, c, to string, using:

在您的代码版本中,您将新读取的字符c分配给string,使用:

*string = c;

*string points at the beginning of the string so you keep replacing the first character of string with the newly read character.

*字符串点在字符串的开头,所以您要不断地用新读的字符替换字符串的第一个字符。

The code you linked to does the following:

您所链接的代码如下:

str[i] = c

Basically, it is assigning the character to the end of the string, using the index i.

基本上,它使用索引i将字符分配到字符串的末尾。

In your version of the code you could use size - 1 instead of i.

在您的版本的代码中,您可以使用size - 1而不是i。

#3


3  

Try changing:

试着改变:

*string = c;

To:

:

string[size-1] = c;

That way you won't just overwrite the first character each time.

这样就不会每次都覆盖第一个字符。

#4


1  

try

试一试

*(string + size - 1) = c;

maybe this helps

也许这可以帮助