如何在C中向数组中输入字符串?

如何在C中向数组中输入字符串?,c,arrays,string,pointers,C,Arrays,String,Pointers,我试图从用户那里获取输入(字符串)并将它们存储在一个数组中。但在我运行了这段代码后,程序立即崩溃 #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]);

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

#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;
}
#包括
int main(){
int i;
字符*字[3];

对于(i=0;i代码
char*word[3]
制作了一个三元素指针数组


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

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

是,由于声明字符数组,代码崩溃
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
 }
指针不够,您需要将指针设置为point 到可以存储字符串的内存

例如

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

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

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

如果您想坚持使用
scanf()
,那么您可以提前使用分配一些空间

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

您可以在代码中应用
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 */
} 
没有scanf的另一种方法 更合适的读取字符串的方法应该是使用

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

有关FGET的注意事项:

  • 在缓冲区末尾追加
    \n
    字符。可以轻松删除
  • 出现错误时,返回
    NULL
    。如果未读取任何字符,则仍会在末尾返回
    NULL
  • 缓冲区必须以给定的大小静态声明
    n
  • 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 */
带有注释的示例代码: 输出:

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

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

虽然您可以使用
scanf
,但在使用
scanf
进行用户输入时,您将很快遇到许多困扰所有新C程序员的陷阱之一(例如,无法处理输入缓冲区中剩余的
“\n”
,无法处理字符串中的空白,无法限制读取/写入的字符数,无法验证读取或处理EOF,等等。)

更好的方法是简单地使用
fgets
,然后修剪
fgets
读取并包含在其存储字符串的缓冲区中的
'\n'

#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;
}

看问题,考虑其他答案,如果有其他问题,请告诉我。

这个基本任务涵盖在任何基本的C书或教程中,而且搜索会为你可以学习的文章带来无数点击量。请在发布新问题之前做基础研究。请看编译器告诉你的内容。应该有警告。阅读警告,尝试理解它们告诉您的内容,并修复它们,以便至少您的程序在编译时不会出现任何警告。根据答案,我开始质疑该注释的第一部分
:)
我重新打开了这个问题,这不仅仅是读取未分配的字符串的问题,而是如何将行读入数组等。提供存储,并用指针引用它,然后在其中存储一个字符串,这没有什么错。哎呀……很快就回答了!对不起,C中没有“whatever hexadecimal”类型。为什么
\if(已定义的|已定义的|已定义的| WIN64)
?程序执行后,终端也可能在linux中关闭,对吗?也就是说,当通过GUI或使用
终端-e运行程序时。“/bin/wordsread”
。是的,这一点说得很好。不过,一般来说,只有windows终端才是问题最严重的。Linux上的终端通常更熟悉(除非使用IDE,否则可能是从中编译的)终端。但为了完整性,您可以删除
#if
#endif
预处理器条件,并让代码在退出前等待按键。(或者使用
uuu linux\uu
测试宏显式测试操作系统)
#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] = '\0';
            } 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;
}
Enter a word: Hello
Enter a word: World
Enter a word: Woohoo
Your strings:
words[0] = Hello
words[1] = World
words[2] = Woohoo
#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;
}
$ ./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