C语言 将字符串作为输入并将它们存储在 C 中的字符数组中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17504122/
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
Taking a string as input and storing them in a character array in C
提问by user2316393
I am stumped on how to store strings in an array in C, with each character kept separately. As an example, if the user inputs hellop, I want to store it in a given array, say userText, with userText[0] = h, userText[1] = e, userText[2] = l, and so on. I know this is easy stuff, but I'm still new. So if anyone could help, it would be great. Please explain how to do this using pointers.
我对如何在 C 中的数组中存储字符串感到困惑,每个字符都分开保存。作为一个示例,如果用户输入hellop,我希望将其存储给定的阵列中,说userText,与userText[0] = h,userText[1] = e,userText[2] = l,等。我知道这很简单,但我还是新手。因此,如果有人可以提供帮助,那就太好了。请解释如何使用指针来做到这一点。
#include<stdio.h>
void main()
{
char a[10],c;
int i=0;
while((c=getchar())!='\n')
{
scanf("%c",&a[i++]);
c=getchar();
}
for(i=0;i<11;i++)
printf("%c",a[i]);
}
The program outputs some garbage value (eoeoeoeo\363) when I type in hellop.
该程序输出一些垃圾值(eoeoeoeo\363当I型中)hellop。
回答by Nobilis
To read input I recommend using the fgetsfunction. It's a nice, safe alternative to scanf.
要读取输入,我建议使用fgets函数。这是一个不错的、安全的替代品scanf。
First let's declare a buffer like so:
首先让我们像这样声明一个缓冲区:
char user_input[20];
Then we can get user input from the command line in the following manner:
然后我们可以通过以下方式从命令行获取用户输入:
fgets(user_input, 20, stdin);
This will store a maximum of 20 characters into the string from the standard inputand it will ensure it is null-terminated. The fact that we've limited the input to the size of the array declared earlier ensures that there's no possibility of buffer overruns.
这将最多将 20 个字符存储到来自标准输入的字符串中,并确保它以null 结尾。我们将输入限制为之前声明的数组大小这一事实确保不会出现缓冲区溢出。
Then let's clear the pesky newline that's been entered into the string using strlen:
然后让我们使用strlen清除输入到字符串中的讨厌的换行符:
user_input[strlen(user_input) -1] = 'printf("The user has entered '%s'\n", user_input);
';
As strlenreturns the size of the string upto the null terminator but without it, we can be sure at that position lies the newline character (\n). We replace it with a null-terminator(\0) so that the string ends there.
由于strlen返回字符串的大小直到空终止符但没有它,我们可以确定在那个位置是换行符 ( \n)。我们用空终止符( \0)替换它,以便字符串在那里结束。
Finally, let's print it using printf:
最后,让我们使用printf打印它:
#include <stdio.h>
To use fgetsand printfyou will need to declare the following header:
要使用fgets,printf您需要声明以下标头:
#include <string.h>
For strlenwe need another header, namely:
因为strlen我们需要另一个标题,即:
#include<stdio.h>
int main()
{
char a[10];
int i=0;
while( (a[i++]=getchar()) != '\n' && i < 10) /* take input from user until it's a newline or equal to 10 */
;
a[i] = ' 1 #include <stdio.h>
2 void main()
3 {
4 char a[10], c;
5 int i = 0;
6 while ((c = getchar()) != '\n')
7 {
8 scanf("%c", &a[i++]);
9 c = getchar();
10 }
11 for (i = 0; i < 11; i++)
12 printf("%c", a[i]);
13 }
'; /* null-terminate the string */
i = 0;
while(a[i] != '#include <stdio.h>
int main(void)
{
char a[10];
int c;
int i;
int n;
for (i = 0; i < sizeof(a) && ((c=getchar()) != EOF && c != '\n')
a[i++] = c;
n = i;
for (i = 0; i < n; i++)
printf("%c", a[i]);
putchar('\n');
return 0;
}
') /* print until we've hit printf("%.*s\n", n, a);
*/
printf("%c",a[i++]);
return 0;
}
Job done.
任务完成。
P.S. If I may address the code you've added to your question.
PS 如果我可以解决您添加到问题中的代码。
mainis normally declared asint mainrather thanvoid mainwhich also requires thatmainreturns a value of some sort. For small apps normallyreturn 0;is put just before the closing brace. This return is used to indicate to the OS if the program executed successfully (0 means everything was OK, non-zero means there was a problem).You are not null-terminating your string which means that if you were to read in any other way other than with a careful loop, you will have problems.
You take input from the user twice- once with
getcharand then withscanf.
main通常被声明为int main而不是void mainwhich 也要求main返回某种类型的值。对于小型应用程序,通常return 0;放在右括号之前。此返回用于向操作系统指示程序是否成功执行(0 表示一切正常,非零表示存在问题)。您不是以空字符结尾的字符串,这意味着如果您以除仔细循环之外的任何其他方式阅读,您将遇到问题。
您从用户那里获取输入两次- 一次使用
getchar,然后使用scanf。
If you insist on using your code I've modified it a bit:
如果您坚持使用您的代码,我已经对其进行了一些修改:
for (i = 0; i < sizeof(a)-1 && ((c=getchar()) != EOF && c != '\n')
a[i++] = c;
a[i] = 'char *a = NULL;
int read;
size_t len;
read = getline(&a, &len, stdin);
//free memory
free(a);
';
It should now work.
它现在应该可以工作了。
回答by Jonathan Leffler
Your code is this (except I've added a bunch of spaces to improve its readability):
您的代码是这样的(除了我添加了一堆空格以提高其可读性):
##代码##Line-by-line analysis:
逐行分析:
- OK (now I've added the space between
#includeand<stdio.h>). - The
main()function returns anint. - OK (it is hard to get an open brace wrong).
- Since the return value of
getchar()is anint, you need to declarecseparately as anint. - OK.
- Needs to account for EOF; should be
while ((c = getchar()) != EOF && c != '\n'). You're still very open to buffer overflow, though. - OK.
- Not OK. This reads another character from standard input, and doesn't check for EOF.
- Not OK. This too reads another character from standard input. But when you go back to the top of the loop, you read another character. So, as things stand, if you type
abcdefgat the program,cis assigned'a'in the loop control, thena[0]is assigned'b', thencis assigned'c', then the loop repeats witha[1]getting'e'. If I'd typed 6 characters plus newline, the loop would terminate cleanly. Because I claimed I typed 7 characters, the third iteration assigns'g'toc, which is not newline, soa[2]gets the newline, and the program waits for more input with thec = getchar();statement at the end of the loop. - OK (ditto close braces).
- Not OK. You don't take into account early termination of the loop, and you unconditionally access a non-existent element
a[10]of the arraya(which only has elements 0..9 — C is not BASIC!). - OK.
- You probably need to output a newline after the
forloop. You shouldreturn 0;at the end ofmain().
- 好的(现在我在
#include和之间添加了空格<stdio.h>)。 - 该
main()函数返回一个int. - 好的(很难弄错一个开放式支架)。
- 由于的返回值
getchar()是 anint,所以需要c单独声明为 anint。 - 好的。
- 需要考虑EOF;应该是
while ((c = getchar()) != EOF && c != '\n')。不过,您仍然对缓冲区溢出持开放态度。 - 好的。
- 不好。这从标准输入中读取另一个字符,并且不检查 EOF。
- 不好。这也从标准输入读取另一个字符。但是当你回到循环的顶部时,你读到了另一个字符。因此,就目前情况而言,如果您
abcdefg在程序中键入,c则'a'在循环控制a[0]中分配'b',然后c分配'c',然后分配,然后循环重复a[1]获取'e'。如果我输入 6 个字符加上换行符,循环将干净地终止。因为我声称我输入了 7 个字符,所以第三次迭代分配'g'给c,它不是换行符,因此a[2]获取换行符,并且程序c = getchar();在循环结束时等待更多输入语句。 - 好的(同样关闭大括号)。
- 不好。您没有考虑循环的提前终止,并且您无条件地访问
a[10]数组中一个不存在的元素a(它只有 0..9 个元素——C 不是 BASIC!)。 - 好的。
- 您可能需要在
for循环后输出换行符。你应该return 0;在main().
Because your input buffer is so short, it will be best to code a length check. If you'd used char a[4096];, I'd probably not have bothered you about it (though even then, there is a small risk of buffer overflow with potentially undesirable consequences). All of this leads to:
因为您的输入缓冲区太短,所以最好编码长度检查。如果您使用过char a[4096];,我可能不会打扰您(尽管如此,缓冲区溢出的风险很小,可能会带来不良后果)。所有这些导致:
Note that neither the original nor the revised code null terminates the string. For the given usage, that is OK. For general use, it is not.
请注意,原始代码和修改后的代码都不会终止字符串。对于给定的用法,没问题。对于一般用途,它不是。
The final forloop in the revised code and the following putchar()could be replaced (safely) by:
for修改后的代码中的最后一个循环和以下内容putchar()可以(安全地)替换为:
This is safe because the length is specified so printf()won't go beyond the initialized data. To create a null terminated string, the input code needs to leave enough space for it:
这是安全的,因为长度是指定的,因此printf()不会超出初始化数据。要创建空终止字符串,输入代码需要为其留出足够的空间:
(Note the sizeof(a)-1!)
(注意sizeof(a)-1!)
回答by Kostia
To read a string into char array:
要将字符串读入字符数组:
##代码##
