char 数组变量在退出函数后被销毁
char array variables are destroyed after exiting from function
我使用 strtok()
在函数中标记我的字符串。将值复制到全局 char
数组后,我打印这些值以确保功能正常。一切正常,但是当我想访问它们时,它们被破坏了。
这是代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int client, count = 0;
volatile char *token_temp[30];
volatile int toknum = 0;
int text_test()
{
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
const char delimiters[3] = "\n";
char *token = strtok(my_tokenised_string_buffer, delimiters);
token_temp[0]= token;
printf("first tokenised value = %s\n", token);
while (token != NULL) {
++toknum;
token = strtok(NULL, delimiters);
token_temp[toknum]= token;
printf("toknum : %d\t", toknum);
printf("token id from inside tokenise loop : %s -> [%u]\n", token_temp[toknum], toknum);
}
printf("\n\n\n");
for (int i = 0; i < toknum; i++) {
printf("token [%d] value in function out of tokenise = %s\n", i, token_temp[i]);
}
return 0;
}
int main()
{
text_test();
printf("\n\n\n");
for (int i = 0; i < toknum; i++) {
printf("token [%d] value in main = %s\n", i, (char *)token_temp[i]);
}
return 0;
}
这是输出
我想将值分配给结构,但它们被遗漏了。
在函数中声明了一个具有自动存储持续时间的本地数组
int text_test()
{
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
//...
退出函数后不会存活
所以指针数组
volatile char *token_temp[30];
将包含无效指针并且取消引用这些指针将调用未定义的行为。
例如,您需要为从数组 my_tokenised_string_buffer
.
中提取的每个字符串动态分配一个字符数组
另一种方法是将数组 my_tokenised_string_buffer
声明为具有指定关键字 static
的静态存储持续时间
static char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
问题是 strtok
调用给出了指向您的 my_tokenised_string_buffer
切片的指针。但是通过退出该函数,my_tokenised_string_buffer
超出范围,因此被您放入堆栈的新数据覆盖。为避免这种情况,您有 2 个解决方案:
或者 my_tokenised_string_buffer
永远不会超出范围,从而生成以下程序:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int client, count =0;
volatile char *token_temp[30];
volatile int toknum = 0;
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK"; // Static, so won't go out of scope
int text_test()
{
const char delimiters[3] = "\n";
char *token = strtok(my_tokenised_string_buffer, delimiters);
token_temp[0]= token;
printf("first tokenised value = %s\n",token);
while (token != NULL)
{
++toknum ;
token = strtok(NULL, delimiters);
token_temp[toknum]= token;
printf("toknum : %d\t",toknum);
printf("token id from inside tokenise loop : %s -> [%u]\n", token_temp[toknum], toknum);
}
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in function out of tokenise = %s\n",i, token_temp[i]);
}
return 0;
}
int main()
{
text_test();
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in main = %s\n",i, token_temp[i]);
}
return 0;
}
或者每次获得新令牌时使用 malloc 复制令牌。但是,您需要以不同方式管理最后一个令牌:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <stdlib.h>
int client, count = 0;
volatile char *token_temp[30];
volatile int toknum = 0;
int text_test()
{
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
const char delimiters[3] = "\n";
char *token = strtok(my_tokenised_string_buffer, delimiters);
token_temp[0] = malloc((1 + strlen(token)) * sizeof(char));
strcpy((char*) token_temp[0], token);
printf("first tokenised value = %s\n",token);
while (token != NULL)
{
++toknum ;
token = strtok(NULL, delimiters);
if (token != NULL) {
token_temp[toknum] = malloc((1 + strlen(token)) * sizeof(char));
strcpy((char*) token_temp[toknum], token);
} else {
token_temp[toknum] = NULL;
}
printf("toknum : %d\t",toknum);
printf("token id from inside tokenise loop : %s -> [%u]\n", token_temp[toknum], toknum);
}
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in function out of tokenise = %s\n", i, token_temp[i]);
}
return 0;
}
int main()
{
text_test();
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in main = %s\n",i, token_temp[i]);
}
return 0;
}
strtok()
是一个令人困惑且容易出错的函数。它的指针 returns 指向被标记化的字符串(为此目的进行了修改)。将这些指针存储到一个全局数组,顺便说一下,不需要 ne volatile
限定,在函数 returns 之后导致未定义的行为,因为数组 my_tokenised_string_buffer
不再有效。
您应该分配令牌的副本并将目标数组作为参数。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int text_test(char *token_temp[], int length) {
char my_tokenised_string_buffer[] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
const char delimiters[] = "\n";
char *token;
int toknum = 0;
token = strtok(my_tokenised_string_buffer, delimiters);
while (toknum + 1 < length && token != NULL) {
token_temp[toknum++]= strdup(token);
token = strtok(NULL, delimiters);
}
token_temp[toknum] = NULL; /* terminate the array with a null pointer */
return toknum; /* return the number of tokens */
}
int main() {
char *token_temp[30];
int array_length = sizeof(token_temp) / sizeof(*token_temp);
int toknum = 0;
toknum = text_test(token_temp, array_length);
/* print the tokens */
for (int i = 0; i < toknum; i++) {
printf("token [%d] value in main = %s\n", i, token_temp[i]);
}
/* free the tokens */
for (int i = 0; i < toknum; i++) {
free(token_temp[i]);
}
return 0;
}
您可以使用此代码来解决您的问题:
enter code here
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
//------------------------------------------------------------
int SpliteMessage(char* input , char sp , char token_temp[10][40])
{
int len = strlen(input);
int i,token_cnt=0,bcnt=0;
for (i=0 ; i<len ; i++)
{
if (input[i] == sp)
{
token_temp[token_cnt][bcnt] = 0;
token_cnt++;
bcnt=0;
}
else
{
token_temp[token_cnt][bcnt] = input[i];
bcnt++;
}
}
return token_cnt;
}
//----------------------------------------------------------------
int main()
{
char buffer[200] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
char t_temp[10][40];
int token_counter = SpliteMessage(buffer , '\n' , t_temp);
printf("\n--------------\n(Token Counter -> %i)\n",token_counter);
for (int i=0 ; i<token_counter ; i++)
printf("token[%i] from main: (%s) \n",i,t_temp[i]);
return 0;
}
关于:
token_temp[toknum]= token;
这只是复制指针,实际需要的是复制数据,。
建议:
token_temp[ toknum ] = strdup( token );
这将创建数据副本,然后将指向该副本的指针放入数组
我使用 strtok()
在函数中标记我的字符串。将值复制到全局 char
数组后,我打印这些值以确保功能正常。一切正常,但是当我想访问它们时,它们被破坏了。
这是代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int client, count = 0;
volatile char *token_temp[30];
volatile int toknum = 0;
int text_test()
{
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
const char delimiters[3] = "\n";
char *token = strtok(my_tokenised_string_buffer, delimiters);
token_temp[0]= token;
printf("first tokenised value = %s\n", token);
while (token != NULL) {
++toknum;
token = strtok(NULL, delimiters);
token_temp[toknum]= token;
printf("toknum : %d\t", toknum);
printf("token id from inside tokenise loop : %s -> [%u]\n", token_temp[toknum], toknum);
}
printf("\n\n\n");
for (int i = 0; i < toknum; i++) {
printf("token [%d] value in function out of tokenise = %s\n", i, token_temp[i]);
}
return 0;
}
int main()
{
text_test();
printf("\n\n\n");
for (int i = 0; i < toknum; i++) {
printf("token [%d] value in main = %s\n", i, (char *)token_temp[i]);
}
return 0;
}
这是输出
我想将值分配给结构,但它们被遗漏了。
在函数中声明了一个具有自动存储持续时间的本地数组
int text_test()
{
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
//...
退出函数后不会存活
所以指针数组
volatile char *token_temp[30];
将包含无效指针并且取消引用这些指针将调用未定义的行为。
例如,您需要为从数组 my_tokenised_string_buffer
.
另一种方法是将数组 my_tokenised_string_buffer
声明为具有指定关键字 static
static char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
问题是 strtok
调用给出了指向您的 my_tokenised_string_buffer
切片的指针。但是通过退出该函数,my_tokenised_string_buffer
超出范围,因此被您放入堆栈的新数据覆盖。为避免这种情况,您有 2 个解决方案:
或者 my_tokenised_string_buffer
永远不会超出范围,从而生成以下程序:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
int client, count =0;
volatile char *token_temp[30];
volatile int toknum = 0;
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK"; // Static, so won't go out of scope
int text_test()
{
const char delimiters[3] = "\n";
char *token = strtok(my_tokenised_string_buffer, delimiters);
token_temp[0]= token;
printf("first tokenised value = %s\n",token);
while (token != NULL)
{
++toknum ;
token = strtok(NULL, delimiters);
token_temp[toknum]= token;
printf("toknum : %d\t",toknum);
printf("token id from inside tokenise loop : %s -> [%u]\n", token_temp[toknum], toknum);
}
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in function out of tokenise = %s\n",i, token_temp[i]);
}
return 0;
}
int main()
{
text_test();
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in main = %s\n",i, token_temp[i]);
}
return 0;
}
或者每次获得新令牌时使用 malloc 复制令牌。但是,您需要以不同方式管理最后一个令牌:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <stdlib.h>
int client, count = 0;
volatile char *token_temp[30];
volatile int toknum = 0;
int text_test()
{
char my_tokenised_string_buffer[255] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
const char delimiters[3] = "\n";
char *token = strtok(my_tokenised_string_buffer, delimiters);
token_temp[0] = malloc((1 + strlen(token)) * sizeof(char));
strcpy((char*) token_temp[0], token);
printf("first tokenised value = %s\n",token);
while (token != NULL)
{
++toknum ;
token = strtok(NULL, delimiters);
if (token != NULL) {
token_temp[toknum] = malloc((1 + strlen(token)) * sizeof(char));
strcpy((char*) token_temp[toknum], token);
} else {
token_temp[toknum] = NULL;
}
printf("toknum : %d\t",toknum);
printf("token id from inside tokenise loop : %s -> [%u]\n", token_temp[toknum], toknum);
}
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in function out of tokenise = %s\n", i, token_temp[i]);
}
return 0;
}
int main()
{
text_test();
printf("\n\n\n");
for(int i = 0; i < toknum;i++)
{
printf("token [%d] value in main = %s\n",i, token_temp[i]);
}
return 0;
}
strtok()
是一个令人困惑且容易出错的函数。它的指针 returns 指向被标记化的字符串(为此目的进行了修改)。将这些指针存储到一个全局数组,顺便说一下,不需要 ne volatile
限定,在函数 returns 之后导致未定义的行为,因为数组 my_tokenised_string_buffer
不再有效。
您应该分配令牌的副本并将目标数组作为参数。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int text_test(char *token_temp[], int length) {
char my_tokenised_string_buffer[] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
const char delimiters[] = "\n";
char *token;
int toknum = 0;
token = strtok(my_tokenised_string_buffer, delimiters);
while (toknum + 1 < length && token != NULL) {
token_temp[toknum++]= strdup(token);
token = strtok(NULL, delimiters);
}
token_temp[toknum] = NULL; /* terminate the array with a null pointer */
return toknum; /* return the number of tokens */
}
int main() {
char *token_temp[30];
int array_length = sizeof(token_temp) / sizeof(*token_temp);
int toknum = 0;
toknum = text_test(token_temp, array_length);
/* print the tokens */
for (int i = 0; i < toknum; i++) {
printf("token [%d] value in main = %s\n", i, token_temp[i]);
}
/* free the tokens */
for (int i = 0; i < toknum; i++) {
free(token_temp[i]);
}
return 0;
}
您可以使用此代码来解决您的问题:
enter code here
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
//------------------------------------------------------------
int SpliteMessage(char* input , char sp , char token_temp[10][40])
{
int len = strlen(input);
int i,token_cnt=0,bcnt=0;
for (i=0 ; i<len ; i++)
{
if (input[i] == sp)
{
token_temp[token_cnt][bcnt] = 0;
token_cnt++;
bcnt=0;
}
else
{
token_temp[token_cnt][bcnt] = input[i];
bcnt++;
}
}
return token_cnt;
}
//----------------------------------------------------------------
int main()
{
char buffer[200] = "Response\n\nCompany\nModel\nRevision: N01234567890\n\nOK";
char t_temp[10][40];
int token_counter = SpliteMessage(buffer , '\n' , t_temp);
printf("\n--------------\n(Token Counter -> %i)\n",token_counter);
for (int i=0 ; i<token_counter ; i++)
printf("token[%i] from main: (%s) \n",i,t_temp[i]);
return 0;
}
关于:
token_temp[toknum]= token;
这只是复制指针,实际需要的是复制数据,。
建议:
token_temp[ toknum ] = strdup( token );
这将创建数据副本,然后将指向该副本的指针放入数组