I am trying to split a string by , and assign them to a struct.
Example string
char t1[] = "185213,Example Name,88";
And I have this struct.
typedef struct {
int studentNumber;
char studentName[200];
int grade;
} STUDENT;
STUDENT students[]= {
{...},
{...},
{...}
}
I want to split the string and push into students struct array. I mean 185213 is number, Example Name is name and 88 is grade.
If you know up front that your strings will always have just three fields, with the format
"%d,%s,%d", then you do not need a complex logic with loops, and input checking, and so on. Something simpler has parsing each element separately would be enough:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int studentNumber;
char *studentName;
int grade;
} STUDENT;
int main(){
STUDENT *student = malloc(sizeof(STUDENT));
student->studentName = malloc(201); // Space for 200 characters + '\0'
char *eptr;
char t1[] = "185213,Example Name,88";
char *token = strtok(t1, ","); // Read studentNumber
student-> studentNumber = strtol(token, &eptr, 10);
token = strtok(NULL, ","); // Read the studentName
strcpy(student->studentName, token);
token = strtok(NULL, ","); // Read the grade
student-> grade = strtol(token, &eptr, 10);
printf("%d\n", student-> studentNumber);
printf("%s\n", student-> studentName);
printf("%d\n", student-> grade);
...
}
You can use the function strtok to parse the strings based on the delimiter ",", the function strcpy to copy the strings parsed from strtok into your struct, and the function strtol to parser the int value from the string read from strtok.
A difference between the STUDENT struct that I have posted and yours, is that the field char *studentName was dynamically allocated (as correctly pointed out on the comments).
You can do this like so (using atoi() from stdlib.h and strcpy from string.h).
char t1[] = "185213,Example Name,88";
char * pch;
STUDENT s;
pch = strtok (t1,",");
if (pch != NULL) s.studentNumber = atoi(pch);
pch = strtok (NULL,",");
if (pch != NULL) strcpy(s.studentName, pch);
pch = strtok (NULL,",");
if (pch != NULL) s.grade = atoi(pch);
Can someone please help me with this problem, I want my program to print + with every end of line.
My code is:
#include <stdio.h>
#include <string.h>
int main()
{
char str[65];
char * pch;
char str1[65];
fgets (str, 100, stdin);
pch = strtok (str," ");
while (pch != NULL)
{
str1=pch;
printf("=");
printf ("%s\n",pch);
pch = strtok (NULL, " ");
}
return 0;
}
With input, "Muhannad Stack" (output wrong):
=Muhannad
=Stack
Correct:
=Muhannad+
=Stack+
Therefore, my problem is how to add + at the end of every printed line
Here is what would work:
#include <stdio.h>
#include <string.h>
int main()
{
char str[65];
char * pch;
char str1[65];
fgets (str, 100, stdin);
pch = strtok (str,"\n");
pch = strtok (pch," ");
while (pch != NULL) {
printf ("=%s+\n",pch);
pch = strtok (NULL, " ");
}
return 0;
}
Hey I'm having problems with my code I get creating the tokens and have it adding it add the tokens to a 2d array but it doesn't work correctly. Any idea why.
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This a sample string";
char * st[4][0];
char * pch;
int i;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ");
for(i=0;i<4;i++)
{
st[i][0]=pch;
}
}
print(st, i);
return 0;
}
void print(char st[4][0], int i)
{
for(i=0;i<4;i++)
{
printf("%d - %s",i ,st[i][0]);
}
}
char * st[4][0];
You are allocating an array of zero length. later you try to access the first element, which is non-existent, and therefore you get undefined behaviour.
I cannot see why this array has two dimensions anyway. You only access the first element of the second dimension, why not:
char * st[4];
??
To be more precise I don't understand the usage of this variable at all. Why do you write the same value in all four elements?
There are a number of problems: compare with this code:
/* strtok example */
#include <stdio.h>
#include <string.h>
void print(char *st[4]) // Fixed parameter type
{
int i; // i is a local counter
for(i=0;i<4;i++)
{
printf("%d - %s\n",i ,st[i]);
}
}
int main ()
{
char str[] ="This a sample string";
char * st[4]; // Corrected array definition
char * pch;
int i=0; // Initialise counter i to 0
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ");
while (pch != NULL)
{
st[i]=pch; // Store string before overwriting pch, and only store in a single location
printf ("%s\n",pch);
pch = strtok (NULL, " ");
i++; // increment i inside loop
}
print(st);
return 0;
}
I have a problem with strtok() - it does not return the input as expected.
void parse_input(const char *input,unsigned char *ctext, int mlen){
char * str = strdup(input);
char * pch = strtok(str,"-");
while (pch != NULL)
{
ctext[mlen] = (int) pch;
pch = strtok (NULL, "-");
mlen++;
}
On input like 1-2-3-4 I would want it to fill ctext with [1,2,3,4].
That doesn't work, however.
What am I doing wrong? Any help appreciated.
ctext[mlen] = (int) pch;
That stores the numeric value of the pointer, whereas you really want the character pointed to by the pointer. Time to read a good article/book/tutorial on pointers.
ctext[mlen] = *pch;
is what you're looking for.
You want to get the character in the first byte of pch -- not the address of pch
ctext[mlen] = *pch;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse_input(const char *input,unsigned char *ctext[], int *mlen){
char * str = strdup(input);
char * pch = strtok(str,"-");
while (pch != NULL){
ctext[(*mlen)++] = (unsigned char*)pch;
pch = strtok (NULL, "-");
}
}
int main(void){
unsigned char *ctext[16];
int mlen=0;
int i;
parse_input("1-2-3-4", ctext, &mlen);
printf("[ ");
for(i=0;i<mlen;++i){
printf("%s", ctext[i]);
if(i<mlen -1)
printf(", ");
}
printf(" ]\n");
//free(ctext[0]);
return 0;
}
I need to divide a C string into tokens. I thought that strtok will be my best try, but I'm getting very strange results...
Here is my test program. In this example I will get 3 tokens with "##" separator but when I try to work with the ones I supposedly had copied, only the third one is shown correctly.. the other two look corrupted or something... I don't know... ?
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define TAM 3 //elements
char** aTokens(char* str, char* delimitador)
{
char* pch;
char** tokens;
int i = 0;
tokens = (char**)malloc(sizeof(char*)*TAM);
pch = strtok(str, delimitador);
while(pch != NULL)
{
tokens[i] = (char*)malloc((sizeof(strlen(pch))+1) * sizeof(char));
strcpy(tokens[i], pch);
pch = strtok(NULL, delimitador);
i++;
}
return tokens;
}
int main ()
{
char str[] = "30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,";
char** tokens;
int i;
tokens = aTokens(str, "##");
for(i = 0; i<TAM; i++)
printf("%d -- %s\n", strlen(tokens[i]), tokens[i]);
//Clean
//for(i = 0; i<TAM; i++)
//free(tokens[i]);
//free(tokens);
return 0;
}
output with GCC on Linux:
13 -- 30117700,1,T <---- ?
13 -- 30117700,1,T <----- ?
115 -- 30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,
I have commented the "clean" section because it provides lots of runtime error too ... :(
Help please!!
I think you are slightly confused on how strtok works.
For the most part, you've got it right. However, the string of separator characters that is given to strtok is not used as a string per se, but it used more like an array of characters, and strtok only cares about these individual characters. So calling strtok with the string "#" is exactly the same as giving it "##". In order to tokenize your string correctly, you need to decide on a single separator character to use, or use a different (perhaps custom) tokenizer function that can handle multi-character separators..
The following line isn't correct. sizeof(strlen(..)) will be 4 (in a 32-bit app) regardless of the length of the string.
tokens[i] = (char*)malloc((sizeof(strlen(pch))+1) * sizeof(char));
It should probably be:
tokens[i] = (char*)malloc((strlen(pch)+1) * sizeof(char));
Standard implementation of strtok:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,"#");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, "#");
}
return 0;
}