In the following piece of code, i see that after breaking userHostPairs
in tokens and assigning to itself doesn't work. 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]);
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 :
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
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
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 :
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 :
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 :
#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 :
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 :
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 $
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.