C语言 如何将字符串输入到C中的数组中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41518039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:33:54  来源:igfitidea点击:

How to input strings into an array in C?

carraysstringpointers

提问by Top Serious

I tried to get the inputs(strings) from user and store them in an array.But after I ran this code, the program instantly crashed.

我试图从用户那里获取输入(字符串)并将它们存储在一个数组中。但是在我运行这段代码后,程序立即崩溃了。

#include <stdio.h>
int main() {
    int i;
    char *word[3];
    for(i=0;i<3;i++)
    {
        printf(" Enter a word: ");
        scanf("%s", &word[i]);
    }
    printf("%s ", word[0]);
    return 0;
}

回答by RoadRunner - MSFT

In this line:

在这一行:

scanf("%s", &word[i]);

You need to make sure word[i]is pointing somewhere, and has enough space to occupy the string entered. Since word[i]is a char *pointer, you need to at some time allocate memory for this. Otherwise, it is just a dangling pointer not pointing anywhere.

您需要确保word[i]指向某个地方,并且有足够的空间来占用输入的字符串。由于word[i]是一个char *指针,因此您有时需要为此分配内存。否则,它只是一个不指向任何地方的悬空指针。

If you want to stick with scanf(), then you can allocate some space beforehand with malloc.

如果你想坚持使用scanf(),那么你可以预先分配一些空间malloc

malloc()allocates requested memory on the heap, then returns a void*pointer at the end.

malloc()在堆上分配请求的内存,然后void*在最后返回一个指针。

You can apply malloc()in your code like this:

您可以malloc()像这样在代码中应用:

size_t malloc_size = 100;

for (i = 0; i < 3; i++) {
    word[i] = malloc(malloc_size * sizeof(char)); /* allocates 100 bytes */
    printf("Enter word: ");
    scanf("%99s", word[i]); /* Use %99s to avoid overflow */
                            /* No need to include & address, since word[i] is already a char* pointer */
} 

Note:Must check return value of malloc(), because it can return NULLwhen unsuccessful.

注意:必须检查 的返回值malloc(),因为它可以NULL在不成功时返回。

Additionally, whenever you allocate memory with the use of malloc(), you must use freeto deallocate requested memory at the end:

此外,每当您使用 分配内存时malloc(),您必须free在最后使用来释放请求的内存:

free(word[i]);
word[i] = NULL; /* safe to make sure pointer is no longer pointing anywhere */

Another approach without scanf

另一种没有 scanf 的方法

A more proper way to read strings should be with fgets.

读取字符串的更正确方法应该是使用fgets.

char *fgets(char *str, int n, FILE *stream)reads a line from an input stream, and copies the bytes over to char *str, which must be given a size of nbytes as a threshold of space it can occupy.

char *fgets(char *str, int n, FILE *stream)从输入流中读取一行,并将字节复制到char *str,必须将n字节大小作为它可以占用的空间阈值。

Things to note about fgets:

fgets 的注意事项:

  • Appends \ncharacter at the end of buffer. Can be removed easily.
  • On error, returns NULL. If no characters are read, still returns NULLat the end.
  • Buffer must be statically declared with a given size n.
  • Reads specified stream. Either from stdinor FILE *.
  • \n在缓冲区末尾追加字符。可以轻松移除。
  • 出错时,返回NULL. 如果没有读取字符,仍然NULL在最后返回。
  • 缓冲区必须以给定的大小静态声明n
  • 读取指定的流。无论是从stdinFILE *

Here is an example of how it can be used to read a line of input from stdin:

以下是如何使用它从 读取一行输入的示例stdin

char buffer[100]; /* statically declared buffer */

printf("Enter a string: ");
fgets(buffer, 100, stdin); /* read line of input into buffer. Needs error checking */

Example code with comments:

带注释的示例代码:

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

#define NUMSTR 3
#define BUFFSIZE 100

int main(void) {
    char *words[NUMSTR];
    char buffer[BUFFSIZE];
    size_t i, count = 0, slen; /* can replace size_t with int if you prefer */

    /* loops only for three input strings */
    for (i = 0; i < NUMSTR; i++) {

        /* read input of one string, with error checking */
        printf("Enter a word: ");
        if (fgets(buffer, BUFFSIZE, stdin) == NULL) {
            fprintf(stderr, "Error reading string into buffer.\n");
            exit(EXIT_FAILURE);
        }

        /* removing newline from buffer, along with checking for overflow from buffer */
        slen = strlen(buffer);
        if (slen > 0) {
            if (buffer[slen-1] == '\n') {
                buffer[slen-1] = '
Enter a word: Hello
Enter a word: World
Enter a word: Woohoo
'; } else { printf("Exceeded buffer length of %d.\n", BUFFSIZE); exit(EXIT_FAILURE); } } /* checking if nothing was entered */ if (!*buffer) { printf("No string entered.\n"); exit(EXIT_FAILURE); } /* allocate space for `words[i]` and null terminator */ words[count] = malloc(strlen(buffer)+1); /* checking return of malloc, very good to do this */ if (!words[count]) { printf("Cannot allocate memory for string.\n"); exit(EXIT_FAILURE); } /* if everything is fine, copy over into your array of pointers */ strcpy(words[count], buffer); /* increment count, ready for next space in array */ count++; } /* reading input is finished, now time to print and free the strings */ printf("\nYour strings:\n"); for (i = 0; i < count; i++) { printf("words[%zu] = %s\n", i, words[i]); free(words[i]); words[i] = NULL; } return 0; }

Example input:

示例输入:

Your strings:
words[0] = Hello
words[1] = World
words[2] = Woohoo

Output:

输出:

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

#define NWDS 3    /* declare a constant for the maximum number of words */

int main (void) {

    int i, n = 0;
    char word[NWDS][50] = { "" };       /* provide storage or allocate */

    for (i = 0; i < NWDS; i++) {        /* for a max of NWDS */
        printf ("Enter word : ");       /* prompt */
        if (!fgets (word[i], sizeof word[i], stdin))  /* read/validate */
            break;                      /* protect against EOF */
        size_t len = strlen (word[i]);  /* get length */
        if (word[i][len-1] == '\n')     /* check for trailing '\n' */
            word[i][--len] = 0;         /* overwrite with nulbyte  */
    }
    n = i;                              /* store number of words read */
    putchar ('\n');                     /* make it pretty */

    for (i = 0; i < n; i++)             /* output each word read */
        printf (" word[%d] : %s\n", i, word[i]);

#if (defined _WIN32 || defined _WIN64)
    getchar();  /* keep terminal open until keypress if on windows */
#endif

    return 0;
}

回答by David C. Rankin

There seems to be a bit of confusion in this area. Your primary problem is you are attempting to write each word to the address ofeach of pointers you declare with char *word[3];. (not to mention you have no storage allocated at the location pointed to by each pointer -- but you never get there as you attempt to write to the address ofeach pointer with &word[i]rather than to the pointer itself)

这方面似乎有些混乱。您的主要问题是要尝试每个字写的地址,每次与声明的指针char *word[3];。(更不用说您没有在每个指针指向的位置分配存储空间——但是当您尝试写入每个指针的地址&word[i]而不是指针本身时,您永远不会到达那里)

While you can use scanfyou will quickly run into one of the many pitfalls with taking user input with scanfthat plague all new C programmers (e.g. failing to handle the '\n'left in the input buffer, failing to handle whitespace in strings, failing to limit the number of characters read/written, failing to validate the read or handle EOF, etc...)

虽然您可以使用,但scanf您很快就会遇到许多陷阱之一,即接收用户输入并scanf困扰所有新的 C 程序员(例如,无法处理'\n'输入缓冲区中的左侧无法处理字符串中的空格无法限制字符读/写无法验证读或手柄EOF等...

A better approach is to simply use fgetsand then trim the '\n'that fgetsread and includesin the buffer to which it stores the string. A simple example would be:

更好的方法是简单地使用fgets,然后修剪'\n'fgets阅读,包括在其所存储的字符串的缓冲区。一个简单的例子是:

$ ./bin/wordsread
Enter word : first word
Enter word : next word
Enter word : last word

 word[0] : first word
 word[1] : next word
 word[2] : last word

Go ahead and cancel input at any time by generating an EOFduring input (ctrl + don Linux or ctrl + zon windoze), you are covered.

通过生成一个EOF期间输入(ctrl + d在 Linux 或ctrl + z在 windoze 上)随时取消输入,你会被覆盖。

Example Use/Output

示例使用/输出

char *word[3]; // <-- this is an array of 3 dangling pointers, of type char*
// they still point nowhere, we later need to set them to some allocated location.
 ...
 for(i=0;i<3;i++) {
     word[i] = malloc(some_max_size * sizeof(char)); // <-- allocate space for your word
     printf(" Enter a word: ");
     scanf("%s", word[i]); // <-- not &word[i]; word[i] is already a char* pointer
 }

Looks things over, consider the other answers, and let me know if you have further questions.

仔细查看,考虑其他答案,如果您还有其他问题,请告诉我。

回答by A.S.H

const int maxLen = 32;
char* word[3] = {NULL,NULL,NULL};

word[i] = malloc(maxLen);

回答by Nithin P

You are declaring word as array of pointer (char *word[3];). You have to allocate memory to store data. Allocate memory with mallocor similar functions before assigning values.

您将 word 声明为指针数组 (char *word[3];)。您必须分配内存来存储数据。在赋值之前使用malloc或类似函数分配内存。

回答by AndersK

Yes the code crashes because declaring an array of character pointers is not enough, you need to set the pointers to point to memory where the strings can be stored.

是的,代码崩溃是因为声明一个字符指针数组是不够的,您需要将指针设置为指向可以存储字符串的内存。

E.g.

例如

printf("Enter a word:");
fgets(word[i],maxLen,stdin);

then read the string from keyboard, to ensure that the string is not too long use fgets and maxLen:

然后从键盘读取字符串,确保字符串不会太长,使用 fgets 和 maxLen:

##代码##

回答by Satyam Raj

The code char *word[3]made a 3-element array of pointers!

该代码char *word[3]制作了一个 3 元素的指针数组!

See, you have basically created a character array of pointers, so you cannot put a "string" into each one of them, because the type of a pointer variable is long hexadecimal.

看,您基本上已经创建了一个指针字符数组,因此您不能在每个指针中放入一个“字符串”,因为指针变量的类型是长十六进制。