[英]Breaking a c string into tokens through strtok
In the following piece of code, i see that after breaking userHostPairs
in tokens and assigning to itself doesn't work. 在下面的代码中,我看到在令牌中破坏
userHostPairs
并将其分配给自己后不起作用。 After breaking into tokens i print userHostPairs
in loop and in the same loop i also print 0th element always through printf("0Printing after strtok = %s",userHostPairs[0]);
分成令牌后,我循环打印
userHostPairs
,并且在同一循环中,我也始终通过printf("0Printing after strtok = %s",userHostPairs[0]);
始终打印第0个元素printf("0Printing after strtok = %s",userHostPairs[0]);
which prints weird values(most probably the last fetched value). 打印奇怪的值(很可能是最后获取的值)。
FILE* fp;
char line[100];
char* userHostPairs[100];
fp = fopen("somefile", "r");
//READING THE FILE LINE BY LINE. WORKS FINE
int count =0;
while (fgets(line, sizeof(line), fp) != NULL ) {
userHostPairs[count]=malloc(MAX_LINE_SIZE);
strcpy(userHostPairs[count],line);
count++;
}
///PROBLEMATIC CODE////////////////////
for(i=0;i<count;i++)
{
char temp[100];
strcpy(temp,userHostPairs[i]);
userHostPairs[i] = strtok(temp,"@");
userHostPairs[i] = strtok(NULL,"@");
printf("Printing after strtok = %s",userHostPairs[i]);
printf("0Printing after strtok = %s",userHostPairs[0]); //This 0th element is always some random(or last) value fetched.
}
}
Output: 输出:
Printing in strtok = 10.238.178.136
0Printing in strtok = 10.238.178.136
Printing in strtok = 10.238.152.101
0Printing in strtok = 10.238.152.101
Printing in strtok = eaasrt
0Printing in strtok = eaasrt
Printing in strtok = eaasrt7
0Printing in strtok = aasrt7
prints weird values(most probably the last fetched value).
打印奇怪的值(很可能是最后获取的值)。
this is because of several errors in your code 这是因为您的代码中有几个错误
char temp[100];
userHostPairs[i] = strtok(temp,"@");
userHostPairs[i] = strtok(NULL,"@");
the assignments are not what you want for 3 reasons : 作业不是您想要的,原因有3个:
Of course when you will go out of the scope of temp any uses to pointer saved in userHostPairs will have an undefined behavior, but this is not the reason of the result you see because your writes are in the scope of temp 当然,当您超出temp的范围时,任何用于userHostPairs中保存的指针的用法都会具有未定义的行为,但这不是您看到的结果的原因,因为您的写入在temp的范围内
Example : 范例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t read(size_t sz, char *a1[sz], char * a2[sz])
{
FILE* fp = fopen("f", "r");
if (fp == 0)
return 0;
char line[50];
size_t rank;
for (rank = 0; rank != sz; ++rank) {
if (fgets(line, sizeof(line), fp) == NULL)
break;
char * p1, * p2;
if (((p1 = strtok(line, "@")) == NULL) ||
((p2 = strtok(NULL, "@\n")) == NULL))
break;
a1[rank] = malloc(strlen(p1) + 1);
strcpy(a1[rank], p1);
a2[rank] = malloc(strlen(p2) + 1);
strcpy(a2[rank], p2);
}
fclose(fp);
return rank;
}
#define N 50
int main()
{
char * a1[N];
char * a2[N];
size_t n = read(N, a1, a2);
for (size_t i = 0; i != n; ++i)
printf("'%s' / '%s'\n", a1[i], a2[i]);
/* ... */
/* free resources */
for (size_t i = 0; i != n; ++i) {
free(a1[i]);
free(a2[i]);
}
return 0;
}
Note if you have strdup you can replace 请注意,如果您有strdup ,则可以替换
a1[rank] = malloc(strlen(p1) + 1);
strcpy(a1[rank], p1);
a2[rank] = malloc(strlen(p2) + 1);
strcpy(a2[rank], p2);
by 通过
a1[rank] = strsup(p1);
a2[rank] = strdup(p2);
Having the file f containing : 文件f包含:
aze@qsd@
wxc@iop
iop@jkl
Compilation and execution : 编译执行:
pi@raspberrypi:/tmp $ ./a.out
'aze' / 'qsd'
'wxc' / 'iop'
'iop' / 'jkl'
pi@raspberrypi:/tmp $
Execution under valgrind : 在valgrind下执行:
pi@raspberrypi:/tmp $ valgrind ./a.out
==6244== Memcheck, a memory error detector
==6244== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6244== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6244== Command: ./a.out
==6244==
'aze' / 'qsd'
'wxc' / 'iop'
'iop' / 'jkl'
==6244==
==6244== HEAP SUMMARY:
==6244== in use at exit: 0 bytes in 0 blocks
==6244== total heap usage: 9 allocs, 9 frees, 5,496 bytes allocated
==6244==
==6244== All heap blocks were freed -- no leaks are possible
==6244==
==6244== For counts of detected and suppressed errors, rerun with: -v
==6244== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi@raspberrypi:/tmp $ cat f
If you do not want to limit the number of elements in the arrays you can use malloc then realloc for the arrays : 如果您不想限制数组中元素的数量,则可以使用malloc然后为数组重新分配 :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t read(char *** a1, char *** a2)
{
*a1 = malloc(0);
*a2 = malloc(0);
FILE* fp = fopen("f", "r");
if (fp == 0)
return 0;
char line[50];
size_t rank = 0;
while (fgets(line, sizeof(line), fp) != NULL) {
char * p1, * p2;
if (((p1 = strtok(line, "@")) == NULL) ||
((p2 = strtok(NULL, "@\n")) == NULL))
break;
*a1 = realloc(*a1, (rank+1) * sizeof(char *));
(*a1)[rank] = malloc(strlen(p1) + 1);
strcpy((*a1)[rank], p1);
*a2 = realloc(*a2, (rank+1) * sizeof(char *));
(*a2)[rank] = malloc(strlen(p2) + 1);
strcpy((*a2)[rank], p2);
rank += 1;
}
fclose(fp);
return rank;
}
int main()
{
char ** a1;
char ** a2;
size_t n = read(&a1, &a2);
for (size_t i = 0; i != n; ++i)
printf("'%s' / '%s'\n", a1[i], a2[i]);
/* ... */
/* free resources */
for (size_t i = 0; i != n; ++i) {
free(a1[i]);
free(a2[i]);
}
free(a1);
free(a2);
return 0;
}
With the same file f , compilation and execution : 使用相同的文件f ,编译和执行:
pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall st.c
pi@raspberrypi:/tmp $ ./a.out
'aze' / 'qsd'
'wxc' / 'iop'
'iop' / 'jkl'
pi@raspberrypi:/tmp $
Execution under valgrind : 在valgrind下执行:
pi@raspberrypi:/tmp $ valgrind ./a.out
==6423== Memcheck, a memory error detector
==6423== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6423== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6423== Command: ./a.out
==6423==
'aze' / 'qsd'
'wxc' / 'iop'
'iop' / 'jkl'
==6423==
==6423== HEAP SUMMARY:
==6423== in use at exit: 0 bytes in 0 blocks
==6423== total heap usage: 17 allocs, 17 frees, 5,544 bytes allocated
==6423==
==6423== All heap blocks were freed -- no leaks are possible
==6423==
==6423== For counts of detected and suppressed errors, rerun with: -v
==6423== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi@raspberrypi:/tmp $
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.