Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am new to C
I am trying to parse the string by "spaces" and "commas", string that *ch pointing to, but I am getting the first element only. Not sure what I am doing wrong, and I have wasted my whole day already on this, but still couldn't figure out.
#include <stdio.h>
#include <string.h>
int main(){
char *ch = "This is a string, and fyunck you.";
char cmd[100], *temp;
int i = 0, size_ch = strlen(ch), count = 0;
/* as strtok only support string array */
for (i = 0; i < size_ch; i++){
if (ch[i] != ','){
cmd[count] = ch[i];
count++;
}
}
cmd[count] = '\0';
printf("cmd: %s\n", cmd);
ch = strtok(cmd, " ");
printf("ch: %s\n", ch);
while ( (ch = strtok(NULL, " ")) != NULL)
printf("%s\n", cmd);
}
Output
cmd: This is a string and fyunck you
ch: This
This
This
This
This
This
This
whereas, the output should be
Desire Output
cmd: This is a string and fyunck you
ch: This
is
a
string
and
fyunck
you
Note: I am not allowed to use external libraries.
P.S I am trying to replicate this code, Code
You're just printing the wrong variable in the last line.
Change
printf("%s\n", cmd);
to
printf("%s\n", ch);
and it should be fine.
Note this:
while ((ch = strtok(NULL, " ")) != NULL)
printf("%s\n", cmd);
You are updating ch, and outputting cmd, which remains unchanged.
To fix this, simply change it to:
while ((ch = strtok(NULL, " ")) != NULL)
printf("%s\n", ch);
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
The code below is giving me problems on Windows Mingw32 but not on WSL Ubuntu. The delimiter is (char)32 (space).
while (!feof(f)){
if(!fgets(line, LINE_LEN, f) || !*line || !strcmp(line, "\n")) continue;
word = strtok(line, &delim);
printf("xd\n");
while(word){
//printf("%s\n",word);s
add_item(h,word);
word = strtok(NULL, &delim);
wc++;
}
lc++;
}
I had tried debugging the code with CLion and the variable 'line' is correctly filled with given sentence that contain spaces, therefore strtok should not be returning null on the first iteration, yet it is. CLion Debug
Please replace that code with this:
// FILE *f presumed to be opened for reading
char line[ 1024 ];
int lc = 0, wc = 0;
while( fgets( line, sizeof line, f ) ) {
for( char *wp = line; ( wp = strtok( wp, " \n" ) ) != NULL; wp = NULL ) {
add_item( h, wp ); // unseen in this question.
wc++;
}
lc++;
}
Empty lines can be safely loaded into line, and strtok() will deal with them correctly (ie: find no words.)
Delim only contained the space character and did not contain the \0 character, therefore it crashed.
EDIT:
More detailed answer by #Joop Eggen below in comments to this answer:
strtok's second parameter is a string of delimiters, like " \t.", and hence a char delim = ' '; and &delim searches next chars till the string terminator '\0'.
The strtok function expects a C string as its second argument (a pointer to a null terminated array of char. delim is presumably defined as char delim = ' '; so &delim is a pointer to char but not a C string because there is a single character and no null terminator. The code has undefined behavior, it may appear to work on some platforms and not on others.
You should instead use a string " \n" or possibly " \t\r\n" as the delimiter string.
Furthermore, you should learn Why is “while( !feof(file) )” always wrong? . The loop should be change to: while (fgets(line, LINE_LEN, f)
Here is a modified version:
int parse_file(FILE *f, struct hash_table_t *h) {
char line[LINE_LEN];
const char *delim = " \t\r\n";
int wc = 0, lc = 0;
while (fgets(line, sizeof line, f)) {
char *p = line;
char *word;
while ((word = strtok(p, delim)) != NULL) {
add_item(h, word);
wc++;
p = NULL;
}
lc++;
}
return wc;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm attempting to replace '%7C' with a '|' in C but i'm getting a multi-character character constant warning. I was wondering if it was possible to do this and if so how? I was attempting using the code below but it gave this warning.
Parse.c
char *parse(char *command){
char * newCommand = (char *)malloc(sizeof(char)*35);
newCommand = strtok(command, " ");
newCommand = strtok(NULL, "/run?command= ");
for(int i = 0; i<strlen(newCommand); i++){
if(newCommand[i] == '+')
{
newCommand[i] = ' ';
}
if(newCommand[i] == '%7C')
{
newCommand[i] = '|';
}
}
return newCommand;
}
Multi-character constants are not portable and should generally be avoided. Your code comes under the 'general' category.
Part of the solution to your problem is to do a string comparison (with strncmp):
if (strncmp(&newCommand[i], "%7C", 3) == 0)
{
newCommand[i] = '|';
}
However, you also need to remove the 7C. That requires more surgery on the loop:
int tgt = 0;
int len = strlen(newCommand);
for (int src = 0; src < len; src++)
{
if (newCommand[src] == '+')
{
newCommand[tgt++] = ' ';
}
else if (strncmp(newCommand[i], "%7C", 3) == 0)
{
newCommand[tgt++] = '|';
src += 2;
}
else
newCommand[tgt++] = newCommand[src];
}
newCommand[tgt] = '\0';
This maintains two indexes into the newCommand array, one from which you're reading (src) and one to which you're writing (tgt — dst would be an alternative name). The src += 2; skips over the 7C after replacing % with |.
Uncompiled code!
Also, in your function you have:
char *newCommand = (char *)malloc(sizeof(char)*35);
newCommand = strtok(command, " ");
This immediately leaks the allocated memory. Maybe you need to use strdup() or:
char *newCommand = malloc(strlen(command) + 1);
if (newCommand == NULL) …report error and bail out…
strcpy(newCommand, command);
And the next line:
newCommand = strtok(NULL, "/run?command= ");
splits on any sequence of any of the characters in the constant string; it does not look for that string. If you want to look for the string, then you need strstr() instead, and you need to run strtok() first, perhaps, to get the right starting point (maybe newCommand = strtok(NULL, ""), then char *end = strstr(newCommand, "/run?command= "); — and check for null pointers returned.
With the revised allocation, you need a new symbol to record the pointers returned by strtok() — such as char *token;.
All in all, there's a lot of work needed on your code.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I've been developing a program to read a data from a file, then I received a Seg Fault when I tried to create a constant size string.
FILE *in = fopen("entrada.txt", "r");
t_mapa *mapa;
t_jogador *jogadores;
jogadores = NULL;
int i, num_jogadores, tamanho_mapa;
char *token1, *token2;
char str1[4], str2[4]; //RIGHT HERE WHEN I CREATE THE STRING, I RECEIVE A SEG FAULT
if(in == NULL){
printf("Arquivo Não pode ser aberto");
}
fscanf(in, "%d", &tamanho_mapa);
printf("%d\n", tamanho_mapa); //Debugger
mapa->mapa = cria_mapa(tamanho_mapa);
preenche_mapa(mapa, in, tamanho_mapa);
fscanf(in, "%d", &num_jogadores);
printf("%d %p\n", num_jogadores, jogadores); //Debugger
jogadores = cria_jogadores(num_jogadores);
for(i=0; i<num_jogadores; i++){
fscanf(in, "%s %s", str1, str2);
token1 = strtok(str2, ",");
token2 = strtok(NULL, ",");
jogadores[i].linha = atoi(token1);
jogadores[i].coluna = atoi(token2);
}
So I have a different theory, I think the next line is the culprit
mapa->mapa = cria_mapa(tamanho_mapa);
That is only if like in the code given here, you defined mapa like this
t_mapa *mapa;
You don't seem to initialise it to anything, but then dereference it using the -> operator.
Other than this I don't see anything wrong directly. We would need more of the code to give a better answer.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
i already have this code in C language, is a string of 15 data delimited by commas the code split the string by comma and store every data in a single variable called array[], the issue is that i have the last data comma if after the last comma there are no data then the variable x15 = 0, but if there are a value after the last , then convert that value to a int. i print the value of the array[15] to verify and this is null, so i out a condition for that but do not work, the program just break after compiling.
char buf[] ="¶bL0 L3,01,+08590323,-079343001,010215,00000000000000,-tN,000,012689997,001219456,000,7FF2,C07F,0,4,";
printf("\n \n string=[%s]\n\n", buf);
int i = 0;
int u;
char *p = strtok (buf, ",");
char *array[16];
char *y15;
while (p != NULL)
{
array[i++] = p;
p = strtok (NULL, ",");
}
for (i = 0; i <16; ++i){
if(array[15] == NULL){
wbt.x15=0;
}else{
wbt.x15=atoi(array[15]);
}
//printf("data: [%s]\n", array[i]);
}
You are using an uninitialized array element, which is cause for undefined behavior.
You have:
char *array[16];
The elements of the array are uninitialized. And then, you proceed to use:
if(array[15] == NULL){
wbt.x15=0;
}else{
wbt.x15=atoi(array[15]);
}
It's not clear why you have that check for every iteration of the loop but that's another problem. The problem with the posted code is that array[15] is not initialized. Using that value is a problem.
Make sure you initialize array properly. Use:
char *array[16] = {0};
Also, I think your for loop needs to be something like:
for (i = 0; i <16; ++i)
{
int x = 0;
if(array[i] != NULL)
{
x = atoi(array[i]);
}
// Now use x.
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying to read a text file line by line and tokenize them into elements of a struck using custom function. Yet I get an infinite loop trying to do so. My code is as follows:
typedef struct
{
char barcodeNumber[5];
char title[50]; char author[30];
char publisherCompany[30];
int publishingYear;
char isbn[13];
} Book;
Book booklist[100];
void readBooks()
{
int i = 0;
char line[255];
printf("asd");
FILE *libraryPtr;
libraryPtr = fopen("books.txt", "r");
if (libraryPtr == NULL)
printf("File not found.\n");
else
{
while (fgets(line, sizeof(line), libraryPtr) != NULL)
{
booklist[i].barcodeNumber = strtok(line, ";");
booklist[i].title = strtok(NULL, ";");
booklist[i].author = strtok(NULL, ";");
booklist[i].publisherCompany = strtok(NULL, ";");
booklist[i].publishingYear = strtok(NULL, ";");
booklist[i].isbn = strtok(NULL, ";");
i++;
}
}
fclose(libraryPtr);
printf("%s", booklist[1].barcodeNumber);
}
My input file is (Books.txt):
A1234;Elements of Theory of Computation;Harry R. Lewis;Prentice Hall;1998;2132457198219
A1987;Knowledge Acquisiton;Karen L. McGraw;Prentice Hall;1989;1945868279220
M3158;Artificial Intelligence;Patrick H. Winston;Addison Wesley;1992;3243568791940
C8287;Linux Sistem Yonetimi;Tom Adelstein;O'Reilly;2007;1718295464178
E6097;CRYPTOGRAPHY AND NETWORK SECURITY PRINCIPLES;William Stallings;Prentice Hall;2007;9780136097044
Strings in C are not like in some high level language, you cannot somply assign strings with the = operator. A complete explanation is beyond the scope of this answer.
You need this inside your while loop (minumum code, no error checking and/or bounds checking done here).
strcpy(booklist[i].barcodeNumber, strtok(line, ";"));
strcpy(booklist[i].title, strtok(NULL, ";"));
strcpy(booklist[i].author, strtok(NULL, ";"));
strcpy(booklist[i].publisherCompany, strtok(NULL, ";"));
char *pyear = strtok(NULL, ";");
booklist[i].publishingYear = atol(pyear);
strcpy(booklist[i].isbn, strtok(NULL, ";"));
i++;
Id didn't test the code, but it should at least give you an idea.
For atol you also need to include:
#include <stdlib.h>
EDIT:
char barcodeNumber[5];
should be
char barcodeNumber[6];
You need space for the terminating zero.
Try this code fragment replacing some of your function code. The errors were due trying to write the strok pointer to a string, instead of copying the string. Apart from being the wrong type, the string pointers became invalid once you moved on to the next line. I also tweaked the way you did the year integer field, and limited the string lengths and the array size i too.
char *ptr;
Book *bookptr;
while (fgets(line, sizeof(line), libraryPtr) != NULL && i < 100) {
bookptr = &booklist[i];
ptr = strtok(line, ";");
if (ptr)
strncpy (bookptr->barcodeNumber, ptr, sizeof(bookptr->barcodeNumber)-1);
// etc...
ptr = strtok(NULL, ";");
if (ptr)
bookptr->publishingYear = atoi (ptr);
// etc...
i++;
}