[英]One dimensional array but multiple string
I want to make a multiple string of array but with just a one dimensional array, Is it possible?我想制作一个多串数组但只有一个一维数组,这可能吗?
#include <stdio.h>
int main()
{
char name1[10];
char name2[10];
printf("Enter name1: ");
scanf("%s", name1);
printf("Enter name2: ");
scanf("%s", name2);
printf("\n%s", name1);
printf("\n%s", name2);
return 0;
}
I just started to learn array and I wanted to try to get multiple input from user and display only specific of the elements.我刚开始学习数组,我想尝试从用户那里获取多个输入并仅显示特定元素。 This is one of the code I tried before but it does not run.
这是我之前尝试过但无法运行的代码之一。
int main()
{
char *name[10];
int i = 1, input;
printf("How many days a week: ");
scanf("%d", &input);
do{
printf("enter day %d: ", i);
scanf("%s", name[i]);
i++;
}while(i < input);
//output wanted
printf("\n%s", name[0]);
printf("\n%s", name[4]);
return 0;
}
A rather peculiar demand, but it could be achieved like this:一个相当特殊的需求,但可以这样实现:
#include <stdio.h>
int main()
{
char names[256];
printf("Enter name1: ");
scanf("%s", names);
printf("Enter name2: ");
scanf("%s", names + strlen(names) + 1);
printf("\n%s", names);
printf("\n%s", names + strlen(names) + 1);
return 0;
}
This way, the strings are concatenated in the array and separated by the terminating 0.这样,字符串在数组中连接起来并由终止 0 分隔。
Your question is very unclear, but it sounds to me that you do not want a one-dimensional array, but rather a two-dimensional array (despite your question explicitly stating the opposite).你的问题很不清楚,但在我看来你不需要一维数组,而是二维数组(尽管你的问题明确说明相反)。
I suggest that you change char *name[10];
我建议你改变
char *name[10];
to char name[10][10];
char name[10][10];
Also, you may want to change the variable name of the 2D-array name
to names
, because that name is misleading, as it implies that it contains only a single string.此外,您可能希望将二维数组
name
的变量名称更改为names
,因为该名称具有误导性,因为它暗示它只包含一个字符串。
Also, you must start the loop counter i
at 0
, not 1
, as array indexes are zero-based in C.此外,您必须从
0
开始循环计数器i
,而不是1
,因为数组索引在 C 中是从零开始的。
After making these changes, your program should look like this:进行这些更改后,您的程序应如下所示:
#include <stdio.h>
int main( void )
{
char names[10][10];
int i = 0, input;
printf("How many days a week: ");
scanf("%d", &input);
do{
printf("Enter day %d: ", i+1);
scanf("%s", names[i]);
i++;
}while(i < input);
//output wanted
printf("The first day is: %s\n", names[0]);
printf("The fifth day is: %s\n", names[4]);
return 0;
}
This program has the following behavior:该程序具有以下行为:
How many days a week: 7
Enter day 1: Monday
Enter day 2: Tuesday
Enter day 3: Wednesday
Enter day 4: Thursday
Enter day 5: Friday
Enter day 6: Saturday
Enter day 7: Sunday
The first day is: Monday
The fifth day is: Friday
Note that the program will write to the array out of bounds if the user enters an integer larger than 10
or if any of the days has a length larger than 9
( 10
including the terminating null character).请注意,如果用户输入大于
10
的 integer 或任何一天的长度大于9
( 10
包括终止字符 null),程序将越界写入数组。
Also, your program would have a cleaner structure if you used a for
loop instead of a while
loop, as it reduces the scope of the loop counter.此外,如果您使用
for
循环而不是while
循环,您的程序将具有更清晰的结构,因为它减少了循环计数器的scope 。
Another issue is that the program will misbehave if the user does not enter a number.另一个问题是,如果用户不输入数字,程序会出现错误。 Instead, it should check if the function
scanf
succeeded, and to print an error message if it did not.相反,它应该检查 function
scanf
是否成功,如果没有成功则打印一条错误消息。
Therefore, it would be better to write it like this:因此,最好这样写:
#include <stdio.h>
#include <stdlib.h>
#define MAX_DAYS 10
//MAX_DAY_LENGTH_FORMAT_STRING, which is used by scanf,
//should always be set to one less than MAX_DAY_LENGTH,
//because the latter also needs room for the terminating
//null character
#define MAX_DAY_LENGTH 10
#define MAX_DAY_LENGTH_FORMAT_STRING "%9s"
int main( void )
{
char names[MAX_DAYS][MAX_DAY_LENGTH];
int num_days;
//prompt user for input
printf( "How many days a week: " );
//attempt to read input
if ( scanf( "%d", &num_days ) != 1 )
{
printf( "Input error!\n" );
exit( EXIT_FAILURE );
}
//verify that input is in desired range
if ( ! ( 1 <= num_days && num_days <= 10 ) )
{
printf( "Input out of range!\n" );
exit( EXIT_FAILURE );
}
for ( int i = 0; i < num_days; i++ )
{
int num_read;
//prompt user for input
printf( "Enter day %d: ", i+1 );
//attempt to read input
if ( scanf( MAX_DAY_LENGTH_FORMAT_STRING "%n", names[i], &num_read ) != 1 )
{
printf( "input error!" );
exit( EXIT_FAILURE );
}
//check whether input was small enough to fit in buffer
if ( num_read == MAX_DAY_LENGTH && getchar() != '\n' )
{
printf( "Input too long to fit in buffer!\n" );
exit( EXIT_FAILURE );
}
}
//print input back to user
printf("The first day is: %s\n", names[0]);
printf("The fifth day is: %s\n", names[4]);
return EXIT_SUCCESS;
}
The program will now perform proper input validation instead of causing undefined behavior on bad input:该程序现在将执行正确的输入验证,而不是在错误输入时导致未定义的行为:
How many days a week: abc
Input error!
How many days a week: 11
Input out of range!
How many days a week: 7
Enter day 1: Monday
Enter day 2: Tuesday
Enter day 3: Wednesdaay
Input too long to fit in buffer!
The reason your code does not work is the array of pointers char *name[10];
您的代码不起作用的原因是指针数组
char *name[10];
is uninitialized so you pass an invalid address name[i]
to scanf()
.未初始化,因此您将无效地址
name[i]
传递给scanf()
。
You can initialize the array explicitly this way:您可以通过这种方式显式初始化数组:
#include <stdio.h>
int main() {
char name0[20], name1[20], name2[20], name3[20], name4[20];
char name5[20], name6[20], name7[20], name8[20], name9[20];
char *name[10] = { name0, name1, name2, name3, name4,
name5, name6, name7, name8, name9 };
int i, input;
printf("How many days a week: ");
if (scanf("%d", &input) != 1 || input < 1 || input > 10) {
fprintf(stderr, "invalid input\n");
return 1;
}
for (i = 0; i < input; i++) {
printf("enter day %d: ", i + 1);
if (scanf("%19s", name[i]) != 1) {
fprintf(stderr, "invalid input\n");
return 1;
}
}
//output wanted
printf("%s\n", name[0]);
if (input > 4)
printf("%s\n", name[4]);
return 0;
}
Alternately, you can use a 2D array:或者,您可以使用二维数组:
#include <stdio.h>
int main() {
char name[10][20];
int i, input;
printf("How many days a week: ");
if (scanf("%d", &input) != 1 || input < 1 || input > 10) {
fprintf(stderr, "invalid input\n");
return 1;
}
for (i = 0; i < input; i++) {
printf("enter day %d: ", i + 1);
if (scanf("%19s", name[i]) != 1) {
fprintf(stderr, "invalid input\n");
return 1;
}
}
//output wanted
printf("%s\n", name[0]);
if (input > 4)
printf("%s\n", name[4]);
return 0;
}
See this beginner string handling FAQ: Common string handling pitfalls in C programming .请参阅初学者字符串处理常见问题解答: C 编程中常见的字符串处理陷阱。 Yours is FAQ #3 - you try to store data using a pointer which isn't pointing at a valid memory location.
你的是常见问题 #3 - 你尝试使用未指向有效 memory 位置的指针存储数据。
char *name[10];
is correct as far as it can be used for the name[i]
syntax to access a string.就其可用于
name[i]
语法访问字符串而言是正确的。 However, it is just an array of pointers which don't point to allocated data yet.然而,它只是一个指针数组,还没有指向分配的数据。 You need to set these pointers to point somewhere before using them.
在使用它们之前,您需要将这些指针设置为指向某处。
One way to do so:这样做的一种方法:
char name1[100];
char name2[100];
char* name[10] = {name1, name2};
...
scanf("%s", name[i]); // now this is fine
Alternatively using dynamic allocation:或者使用动态分配:
#include <stdlib.h>
...
char* name[10];
for(int i=0; i<10; i++)
{
name[i] = malloc(100);
if(name[i]==NULL) { /* handle error */ return 0; }
}
...
scanf("%s", name[i]); // now this is fine
...
for(int i=0; i<10; i++) // cleanup
{
free(name[i]);
}
The advantage of dynamic allocation is that we can realloc
a string later in runtime to change the string length.动态分配的好处是我们可以
realloc
在运行时重新分配一个字符串来改变字符串的长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.