How to split string and assign them to struct - c

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);

Related

converting specific part of string to integer

*updated with how i stored the string into my struct
I have a struct as below:
struct patient {
char name[30], ID[8];
int age, phoneNo;
};
and i've written the following code:
int searchName()
{
char search[30];
char record[60];
const char s[2] = ",";
struct patient c;
char a[8];
int IDno;
FILE* fPtr;
fPtr = fopen("patient.txt", "r");
printf("Enter name to search : ");
getchar();
fgets(search, 30, stdin);
//remove the '\n' at the end of string
search[strcspn(search, "\n")] = 0;
while (fgets(record, 60, fPtr))
{
// strstr returns start address of substring in case if present
if (strstr(record, search))
{
char* pStr = strtok(record, ",");
if (pStr != NULL) {
strcpy(c.ID, pStr);
}
pStr = strtok(NULL, ",");
if (pStr != NULL) {
strcpy(c.name, pStr);
}
pStr = strtok(NULL, ",");
if (pStr != NULL) {
c.age = atoi(pStr);
}
pStr = strtok(NULL, ",");
if (pStr != NULL) {
c.phoneNo = atoi(pStr);
}
}
}
printf("%s", c.ID);
strcpy(a, c.ID);
printf("\n%s", a);
IDno = atoi(a);
printf("\n%d", IDno);
return 0;
}
the code allows me to search for a string in a file, separate the string into smaller strings using strtok, then store them into the struct. suppose i stored a string "PT3" into c.ID in the struct. in my program, I am trying to copy the string of "PT3" from c.ID to a, then convert a to an integer IDno using atoi. I'm not too sure about this, but I think by using atoi to convert "PT3" to an integer, only the integer "3" will remain in IDno, which is exactly when I want.
edit: the problem appears to be that i am unable to convert "PT3" to an integer using atoi. would appreciate help on getting the number "3" from "PT3" to be stored into IDno.
As per your problem description, looks like you need sscanf(). Something like
sscanf(a, "PT%d", &IDno);
should do the job. Don't forget to do the error check.

break a string into 'first' and 'second'

I have read through countless strtok posts, even copied some directly in their entirety into a new int main, but I can't figure out how to create the functions get_first and get_second.
get_first("This is a sentence."); //returns "This"
get_rest("This is a sentence."); //returns "is"
This is what I have so far, I have had nothing but trouble with strtok, but I don't know what else to use.
#include <stdio.h>
#include <string.h>
char * get_first(char * string) {
string = strtok(string, " ");
return string;
}
char * get_second(char * string) {
string = strtok(string, " ");
string = strtok(NULL, " ");
return string;
}
int main(int argc, char * argv[]) {
char * test_string = "This is a sentence.";
char * first = get_first(test_string);
char * second = get_second(test_string);
printf("%s\n", first);
printf("%s\n", second);
}
Getting no faults compiling with gcc -g -Wall, but it always seg faults. I think I have tried every permutation of char c[] and char * c there is.
strtok changes the string. (but String literals are not allowed to change.)
So create a copy.
Do the following:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * get_first(const char *string){
char *clone = strdup(string);//create copy, strdup is non standard. malloc and copy.
char *token = strtok(clone, " ");
if(token)
token = strdup(token);
free(clone);
return token;
}
char * get_second(const char *string) {
char *clone = strdup(string);
char *token = strtok(clone, " ");
if(token && (token = strtok(NULL, " ")))
token = strdup(token);
free(clone);
return token;
}
int main(void) {
char * test_string = "This is a sentence.";
char * first = get_first(test_string);
char * second = get_second(test_string);
printf("%s\n", first);
printf("%s\n", second);
free(first);
free(second);
}

issue to extract token from sub token using strtok() function in c

Have written following code in c
#include "stdio.h"
#include "string.h"
int main()
{
char str[] = "gatway=10.253.1.0,netmask=255.255.0.0,subnet=10.253.0.0,dns=10.253.0.203";
char name[100],value[100];
char *token1,*token2;
char *commasp = ", ";
char *equ="=";
token1 = strtok(str,commasp);
while(token1 != NULL)
{
token2 = strtok(token1,equ);
sprintf(name,"%s",token2);
token2 = strtok(NULL,commasp);
sprintf(value,"%s",token2);
printf("Name:%s Value:%s\n",name,value);
token1 = strtok(NULL,commasp);
}
return 0;
}
My problem is i got only one printf like Name:gatway Value:10.253.1.0. i know last strtok() in while loop followed by previous strok() which turns to null so token1 get null value and break the loop. Have think solution for it to not use strtok() in while loop for sub token (getting name and value) and use other method to extract name and value but it seems to lengthy code(using for or while loop for character match).So any one have batter solution to packup code in single loop.
You could use strtok_r instead of strtok.
char *key_value;
char *key_value_s;
key_value = strtok_r(str, ",", &key_value_s);
while (key_value) {
char *key, *value, *s;
key = strtok_r(key_value, "=", &s);
value = strtok_r(NULL, "=", &s);
printf("%s equals %s\n", key, value);
key_value = strtok_r(NULL, ",", &key_value_s);
}
gatway equals 10.253.1.0
netmask equals 255.255.0.0
subnet equals 10.253.0.0
dns equals 10.253.0.203
Frankly though I think it would be easier to just look for , and when you find one look for = backwards.
You can do this in two steps, first parse the main string:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "gatway=10.253.1.0,netmask=255.255.0.0,subnet=10.253.0.0,dns=10.253.0.203";
char name[100],value[100];
char *commasp = ", ";
char *ptr[256], **t = ptr, *s = str;
*t = strtok(str, commasp);
while (*t) {
t++;
*t = strtok(0, commasp);
}
for (t = ptr; *t; t++) {
printf("%s\n", *t);
// now do strtok for '=' ...
}
return 0;
}
Then parse individual pairs as before.
The above results in:
gatway=10.253.1.0
netmask=255.255.0.0
subnet=10.253.0.0
dns=10.253.0.203

Taking apart strings in C

I have a string that includes two names and a comma how can i take them apart nd write them to seperate strings.
Example
char *line="John Smith,Jane Smith";
I am thinking of using sscanf function.
sscanf(line,"%s,%s",str1,str2);
What should i do?
note: I can change comma to space character.
I am thinking of using sscanf function.
Don't even think about it.
char line[] = "John Smith,Jane Smith";
char *comma = strchr(line, ',');
*comma = 0;
char *firstName = line;
char *secondName = comma + 1;
Here's how you could do it using strtok:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// Your string.
char *line = "John Smith,10,Jane Smith";
// Let's work with a copy of your string.
char *line_copy = malloc(1 + strlen(line));
strcpy(line_copy, line);
// Get the first person.
char *pointer = strtok(line_copy, ",");
char *first = malloc(1 + strlen(pointer));
strcpy(first, pointer);
// Skip the number.
strtok(NULL, ",");
// Get the second person.
pointer = strtok(NULL, ",");
char *second = malloc(1 + strlen(pointer));
strcpy(second, pointer);
// Print.
printf("%s\n%s", first, second);
return 0;
}

How can I fix this strtok() call

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;
}

Resources