C 中的字符串数组

发布于 2024-09-19 06:26:13 字数 509 浏览 12 评论 0原文

我需要保存一个 C 字符串数组。现在我知道 C 字符串只是一个字符数组,所以本质上我想要的是一个二维字符数组。我尝试存储的字符串也不会超过 6 个字符。我的计划是用 50 个“字符串槽”初始化一个 char 数组,然后如果我达到 50 个字符串,则重新分配数组的内存以将其容量加倍。我尝试过一些简单的方法,例如:

int main() {
    char strings[50][6];
    strings[0] = "test";
    printf("The string is: %s", strings[0]);
    return(0);
}

但是,当我编译它时,出现以下错误:

test.c:在函数“main”中:test.c:3: 错误:不兼容的类型 从类型分配给类型“char[6]” 'char *' test.c:4:警告: 不兼容的隐式声明 内置函数“printf”

有人能指出我正确的方向吗?

I need to hold an array of C strings. Now I know C strings are just an array of chars so essentially what I want is a 2d array of chars. The strings I'm trying to store will also never exceed 6 characters. My plan is to initialize a char array with 50 "string slots" and then if I hit 50 strings reallocate the array's memory to double it's capacity. I've tried something simple like:

int main() {
    char strings[50][6];
    strings[0] = "test";
    printf("The string is: %s", strings[0]);
    return(0);
}

But, when I go to compile it I get the following error:

test.c: In function ‘main’: test.c:3:
error: incompatible types when
assigning to type ‘char[6]’ from type
‘char *’ test.c:4: warning:
incompatible implicit declaration of
built-in function ‘printf’

Can anyone point in me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

月寒剑心 2024-09-26 06:26:13

strncpy(strings[0], "test", 6); 除非您的 C 库具有 strlcpy()。但是,如果您需要改变存储的大小,最好将 char **malloc()realloc() 一起使用free()

strncpy(strings[0], "test", 6); unless your C library has strlcpy(). However if you are going to need to vary the size of the storage, you're better off using a char ** with malloc(), realloc() and free().

半仙 2024-09-26 06:26:13

不能以这种方式直接分配数组。在您当前的情况下,您需要执行类似的操作...

strcpy (strings[0], "test");

不过,使用指针数组会更惯用。看看 K & 的 p111 及以后的内容。 R。

One can't assign arrays directly in that way. In your current case, you would need to do something like...

strcpy (strings[0], "test");

It would be more idiomatic to use an array of pointers, though. Have a look at p111 and onwards of K & R.

哀由 2024-09-26 06:26:13

使用 strncpy (如果可能的话)或 strcpy 来完成作业。

Use strncpy (if at all possible) or strcpy for your assignment.

多孤肩上扛 2024-09-26 06:26:13

首先是简单的部分。您确实需要

#include <stdio.h>

消除不兼容的 printf 警告。这与标准所说的 C 工作方式有关,即允许您创建一些与标准 printf 不同的函数,该函数的隐式声明及其签名由编译器(错误地)猜测,并且编译器知道虽然你可以定义一个不同的 printf 但你可能实际上并不是故意的。

好的,现在是更复杂的部分。 C 中的数组有点特殊。可以计算为指针文字(无法分配给它,这类似于尝试 6 = 4;),或者它们可以计算为整个数组,具体取决于上下文。通常它们是指针文字,但在这种情况下,strings[0] 被视为一个数组,这就是为什么您会收到错误,而不是指出strings[0] code> 是无效的左值(左值,表示可以位于 = 左侧的内容)。无论哪种方式,您都无法将字符指针文字(这就是“test”的计算结果)复制到数组。但是,当您在声明字符串(字符数组)的行上执行此操作时,编译器会以不同的方式对待它,这可能会导致一些混乱。无论如何,您需要使用 strcpy 复制组成“test”的字符,或者将 strings[0] 初始化为“test”,如下所示:

char strings[50][6] = { "test" };  // only initializes the first member of the array

First the easy part. You do need to

#include <stdio.h>

to get rid of the incompatible printf warning. This has to do with the way the standard says C works, which is to allow you to make some function that is unlike the standard printf, the implicit declaration of that function with its signature (incorrectly) guessed by the compiler, and the compiler knowing that while you can define a different printf you probably didn't actually mean to.

Ok, now the more complicated part. Arrays in C are a little special. The can evaluate to pointer literals (which can't be assigned to, which is similar to trying to 6 = 4;), or they can evaluate to an entire array, depending on context. Usually they are pointer literals, but in this case strings[0] is seen as an array, which is why you get the error you got rather than one stating that strings[0] was an invalid l-value (left-value, meaning something that can be on the left side of a =). Either way you can't copy a character pointer literal (which is what "test" evaluates to) to an array. When you do this on the line where you declare a string (char array) the compiler treats it differently, though, which can cause some confusion. Anyway, you need to either use strcpy to copy the characters that make up "test" or initialize strings[0] to "test" like this:

char strings[50][6] = { "test" };  // only initializes the first member of the array
陈甜 2024-09-26 06:26:13

您无法使用 = 运算符分配数组内容。首先,数组对象不能成为赋值运算符的目标(在线 C 标准,草案 n1256,第 6.5.16.1 节,第 1 段)。 strings[0]char[6] 类型的数组对象,因此它不能出现在 = 运算符的 LHS 上。

其次,当数组表达式不是 sizeof 或 address-of & 运算符的操作数并且不是用于初始化内容的字符串文字时另一个数组,表达式的类型从“T 的 N 元素数组”隐式转换(“衰减”)为“指向 T 的指针”,并且表达式的值是数组中第一个元素的地址(节6.3.2.1,第 3 段)。

字符串文字“test”是一个 5 元素的 char 数组(C++ 中的 const char),具有静态范围(意味着它的内存在程序启动时分配并保存)直到程序退出)。但是,当它出现在表达式中时,

strings[0] = "test";

其类型从“5 元素 char 数组”转换为“指向 char 的指针”,并且其值是第一个元素的地址,因此您最终要做的是尝试分配 < em>指向数组对象的指针值,该对象不是兼容类型;坏juju,无论如何都无法分配数组对象。

如果要将一个数组的内容复制到另一个数组,则需要单独分配每个数组元素,例如

strings[0][0] = 't';
strings[0][1] = 'e';
strings[0][2] = 's';
strings[0][3] = 't';
strings[0][4] = 0;

或 甚至

size_t len = strlen("test");
size_t i;
for (i = 0; i < sizeof strings[0] - 1 && i < len; i++)
  strings[0][i] = "test"[i]; // yes, you can subscript a string literal
strings[0][i] = 0;

,或者使用库函数,例如 memcpy()strcpy ()strncpy()strcat()sprintf() 等:

strcpy(strings[0], "test");

strncpy(strings[0], "test", sizeof strings[0] - 1); // -1 to leave room
                                                    // for 0 terminator
                                                    // if necessary  

sprintf(strings[0], "%*s", (int) sizeof strings[0] - 1, "test");

请注意,您可以在声明数组时初始化数组的内容,如下所示:

char foo[] = "test";      // foo is implicitly sized to 5 (+1 for 0 terminator)
int  bar[] = {1,2,3,4,5}; // again, size is implied from initializer

float f[3] = {1.0, 2.0, 3.0}; // Initializer cannot contain more items than 
                              // array is sized for

我看到关于使用 strcpy()strncpy() 的使用存在着一场愉快的战争在另一个答案的评论中;我的立场是使用适合特定情况的任何一种。如果您知道缓冲区足够大,可以处理尽可能大的输入,请使用 strcpy()。如果没有,请使用 strncpy(),但请注意,您可能需要手动添加 0 终止符。

You can't assign array contents using the = operator. First of all, an array object cannot be a target of the assignment operator (Online C Standard, draft n1256, section 6.5.16.1, paragraph 1). strings[0] is an array object of type char [6], so it can't appear on the LHS of the = operator.

Second of all, when an array expression is not an operand of either the sizeof or address-of & operators and is not a string literal being used to initialize the contents of another array, the type of the expression is implicitly converted ("decays") from "N-element array of T" to "pointer to T", and the value of the expression is the address of the first element in the array (section 6.3.2.1, paragraph 3).

The string literal "test" is a 5-element array of char (const char in C++) with static extent (meaning the memory for it is allocated at program startup and held until the program exits). However, when it appears in the expression

strings[0] = "test";

its type is converted from "5-element array of char" to "pointer to char" and its value is the address of the first element, so what you wind up doing is attempting to assign a pointer value to an array object, which is not a compatible type; bad juju, over and above not being able to assign an array object anyway.

If you want to copy the contents of one array to another, then you will need to either assign each array element individually, such as

strings[0][0] = 't';
strings[0][1] = 'e';
strings[0][2] = 's';
strings[0][3] = 't';
strings[0][4] = 0;

or even

size_t len = strlen("test");
size_t i;
for (i = 0; i < sizeof strings[0] - 1 && i < len; i++)
  strings[0][i] = "test"[i]; // yes, you can subscript a string literal
strings[0][i] = 0;

or use a library function like memcpy(), strcpy(), strncpy(), strcat(), sprintf(), etc.:

strcpy(strings[0], "test");

or

strncpy(strings[0], "test", sizeof strings[0] - 1); // -1 to leave room
                                                    // for 0 terminator
                                                    // if necessary  

or

sprintf(strings[0], "%*s", (int) sizeof strings[0] - 1, "test");

Note that you can initialize the array's contents when you declare it, like so:

char foo[] = "test";      // foo is implicitly sized to 5 (+1 for 0 terminator)
int  bar[] = {1,2,3,4,5}; // again, size is implied from initializer

float f[3] = {1.0, 2.0, 3.0}; // Initializer cannot contain more items than 
                              // array is sized for

I see there's a merry war over the use of strcpy() vs. strncpy() in the comments to another answer; my position is to use whichever one is appropriate to the given situation. If you know that your buffers are big enough to handle the largest possible input, use strcpy(). If not, use strncpy(), but be aware that you may have to add the 0 terminator manually.

唐婉 2024-09-26 06:26:13

您遇到的问题在于编译器解释语句 char strings[50][6]; 的方式,

而不是您希望的那样,而是一个具有 50 个插槽的 char 数组6 个 char 字符串,您得到了一个由尺寸为 50x6 的单个 char 组成的 char 数组。

您想要初始化数组的方式不是 char strings[50][6];,而是如下(我只知道如何在堆上执行此操作,抱歉):

char ** strings[50] = malloc(50 * sizeof(char *));
for(int i = 0; i < 50; ++i)
{
    strings[i] = malloc(50 * 6 * sizeof(char *));
}

不要忘记之后用frees清理。

编辑:如上所述。在你的 main 方法之前。包含行 #include。这是 printf() 函数所在的位置。

The problem you have is in the way that the compiler interprets the statement char strings[50][6];

Instead of what you hoped, a char array with 50 slots for 6 char strings, you got a char array of single chars with dimesions 50x6.

Rather than char strings[50][6];, the way you want to initialise your array is as follows (I only know how to do this on the heap, sorry):

char ** strings[50] = malloc(50 * sizeof(char *));
for(int i = 0; i < 50; ++i)
{
    strings[i] = malloc(50 * 6 * sizeof(char *));
}

Don't forget to clean with frees afterwards.

EDIT: And as said above. Before your main method. Inlcude the line #include <stdio.h>. This is where the printf() function is located.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文