Getting string between two given characters - c

quote
I have input something like !Hello world! - 123 123 - and I need to get it into struct { char *string; int a; int b;} Can you help me?
typedef struct {
int a;
int b;
char *string;
} Smth;
//-----------(size=(already known size of input))
Smth *smth = (*Smth)malloc(sizeof(smth));
smth.string = (char*)malloc(sizeof(char) * size);
sscanf(input, "!%[^!]! - %d %d - ", smth.string, &smth.a, &smth.b); // doesn't work for me

before you edit your question
the call
sscanf("!%[^!]! - %d %d - ",string,&a,&b);
is not the one you want, you missed to give the string to parse as the first argument, so the string to parse is the format you wanted to use and the used format is the perhaps not initialized value of string
You wanted :
#include <stdio.h>
int main()
{
char string[32];
int a,b;
const char * i = "!Hello world! - 123 123 -";
if (sscanf(i, "!%31[^!]! - %d %d - ", string,&a,&b) == 3)
printf("'%s' %d %d\n", string, a, b);
else
put("error");
return 0;
}
does the work :
pi#raspberrypi:/tmp $ gcc -Wall f.c
pi#raspberrypi:/tmp $ ./a.out
'Hello world' 123 123
pi#raspberrypi:/tmp $
Notice I added in your original format a max length for the read string to not take the risk to write out of string and then to have an undefined behavior. If you do not want to manage yourself the array for string you can use the option %m but is not always available.

You are lacking the input string for sscanf. See example below.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a;
int b;
char *string;
} Smth;
int main(void)
{
Smth smth;
sscanf(
"!Hello world! - 123 123 -",
"!%m[^!]! - %i %i -",
&smth.string,
&smth.a,
&smth.b);
printf("Str: `%s' a:%d b:%d\n", smth.string, smth.a, smth.b);
free(smth.string);
return 0;
}
UPDATE: Given your change in question
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a;
int b;
char* string;
} Smth;
int main(void)
{
size_t size = 30u;
char input[] = "!Hello world! - 123 123 -";
Smth* smth = (Smth*) malloc(sizeof(Smth));
smth->string = (char*) malloc(sizeof(char) * size);
sscanf(input, "!%29[^!]! - %d %d - ", smth->string, &smth->a, &smth->b);
printf("Str: %s a:%d b:%d\n", smth->string, smth->a, smth->b);
free(smth->string);
free(smth);
return 0;
}

Related

how to dynamically populate a string array in c and why by removing unnecessary code the program doesn't work?

i'm trying to populate an array of strings in c using dynamic allocation, this is the code snippet
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct test_struct {
char **names;
int age;
} test_struct;
void add_names(char*** array, int number_of_names);
int main() {
test_struct* ts;
char **array;
int number_of_names;
ts = (test_struct*)malloc(sizeof(test_struct));
printf("input the number of names to add: ");
scanf("%d", &number_of_names);
add_names(&array, number_of_names);
printf("%s | %s\n", array[1], array[0]);
return 0;
}
void add_names(char*** array, int number_of_names) {
char *string;
*array = malloc(sizeof(char*)*number_of_names);
for (int i = 0; i < number_of_names; i++){
scanf("%ms", &string);
*array[i] = malloc(sizeof(char)*strlen(string) + 1);
strcpy(*array[i], string);
}
printf("%s | %s\n", *array[0], *array[1]);
}
If I try to populate it with three names I can't get over the second, and if I try to do it with two names the printf statement inside the function prints both names, however the one in the main function prints ( [name1] | (null) )
.
Also if I remove the unnecessary struct part, I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void add_names(char*** array, int number_of_names);
int main() {
char **array;
int number_of_names;
printf("input the number of names to add: ");
scanf("%d", &number_of_names);
add_names(&array, number_of_names);
printf("%s | %s\n", array[1], array[0]);
return 0;
}
void add_names(char*** array, int number_of_names) {
char *string;
*array = malloc(sizeof(char*)*number_of_names);
for (int i = 0; i < number_of_names; i++) {
scanf("%ms", &string);
*array[i] = malloc(sizeof(char)*strlen(string) + 1);
strcpy(*array[i], string);
}
printf("%s | %s\n", *array[0], *array[1]);
}
That doesn't even work with 2 as input. What am I doing wrong here?

How to duplicate pointer to type int into uint8_t array inside structure array?

I am writing a program which will read the file and save values in arrays.
this is my file:
communication1 : b8:27:eb:cf:54:2c, b8:27:eb:75:85:e4, 2000000;
communication2 : mm:27:eb:cf:54:2c, xx:27:eb:75:85:e4, 2200000;
This is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
struct mac{
uint8_t address_bytes [6];
};
void main(){
int count = 2, i = 0;
char *Trash[4], *Time[4];
int k=0;
int mac1[6], mac2[6];
char tempbuff[100];
char trash[20], mac_s[20], mac_d[20], time[20];
struct mac Mac1[2], Mac2[2];
int j = 0;
FILE *fptr = fopen("config", "r");
fseek(fptr, 0, SEEK_SET);
while(!feof(fptr)){
if (fgets(tempbuff,100,fptr)) {
printf("\n%s", tempbuff);
sscanf(tempbuff, "%15s : %17[^;], %17[^;], %17[^;];", trash, mac_s, mac_d, time);
Trash[i] = strdup(trash);
Time[i] = strdup(time);
sscanf(mac_s, "%x:%x:%x:%x:%x:%x", &mac1[0], &mac1[1], &mac1[2], &mac1[3], &mac1[4], &mac1[5]);
sscanf(mac_d, "%x:%x:%x:%x:%x:%x", &mac2[0], &mac2[1], &mac2[2], &mac2[3], &mac2[4], &mac2[5]);
for(j = 0; j < 6; j++){
Mac1[i].address_bytes[j] = (uint8_t) mac1[j];
Mac2[i].address_bytes[j] = (uint8_t) mac2[j];
}
printf ("Mac1[%d] is %02x:%02x:%02x:%02x:%02x:%02x and Time is %s\n", i, Mac1[i].address_bytes[0], Mac1[i].address_bytes[1], Mac1[i].address_bytes[2], Mac1[i].address_bytes[3],
Mac1[i].address_bytes[4], Mac1[i].address_bytes[5], Time[i]);
printf ("Mac2[%d] is %02x:%02x:%02x:%02x:%02x:%02x \n", i, Mac2[i].address_bytes[0], Mac2[i].address_bytes[1], Mac2[i].address_bytes[2], Mac2[i].address_bytes[3],
Mac2[i].address_bytes[4], Mac2[i].address_bytes[5]);
}
i++;
}
printf(" \n time0 is %s time1 is %s \n", Time[0], Time[1]);
fclose(fptr);
}
As you see, I am sscanf file and take 4 variables, than separately I sscanf mac addresses as pointers to type int and than trying to write them to a structure array. I have to achieve uint8_t values.
Output of this code is:
communication1 : b8:27:eb:cf:54:2c, b8:27:eb:75:85:e4, 2000000;
Mac1[0] is b8:27:eb:cf:54:2c and Time is 2000000
Mac2[0] is b8:27:eb:75:85:e4
communication2 : mm:27:eb:cf:54:2c, xx:27:eb:75:85:e4, 2200000;
Mac1[1] is b8:27:eb:cf:54:2c and Time is 2200000
Mac2[1] is b8:27:eb:75:85:e4
time0 is 2000000 time1 is 2200000
The problem is, that I can't find the way to duplicate pointers into uint8_t field of structure array. With strings I already got the hint - strdup, what about uint8_t?
To copy plain bytes like uint8_t, use memcpy:
int main() {
uint8_t s[6] = { 0x1, 0x2, 0x3,0x4,0x5,0x6 };
uint8_t *t;
t = malloc(6*sizeof(uint8_t));
memcpy(t,s,6*sizeof(uint8_t));
printf("%x %x %x %x %x %x\n", t[0],t[1],t[2],t[3],t[4],t[5]);
}

C - printf string with array of structures

I am new with programming, after searching and searching, i got some code to work (partially), i can create a struct but i can't print string fields :/
#include <stdio.h>
#define MAX 100
struct vehiculos{
float peso;
int hora;
char *id;
int ferry;
};
void asignar(struct vehiculos llegada[MAX] ...) { // Here i have more parameters, but they are useless in this question...
int id,i;
i=0;
while(!feof(input_file)){
fscanf(input_file,"%f %d %s %d",&llegada[i].peso,&llegada[i].hora,id,&llegada[i].ferry);
llegada[i].id = id;
i++;
}
}
int main(){
struct vehiculos llegada[MAX];
FILE *entrada;
entrada = fopen("proy1.txt","r");
asignar(llegada...);
return 0;
}
My problem is that everything works fine in that "asignar" function, but if i try to print the vehicle's id outside that function, it just print garbage values, however other values like peso, hora and ferry are printed correctly (outside the function)
This works:
void asignar(...){
...
printf("%s", llegada[i].id);
...
}
This doesn't work:
int main(){
...
printf("%s", llegada[i].id);
...
}
Also my compiler says that there are no errors in the code, so i don't know what is the problem here
Can anyone help me? it would be great, Thanks :)
In the best case you may get some random garbage. However, most likely your program will just segfault: Your codes declares id, but doesn't allocate space for it.
You need to declare it as
char id[IDLEN]
But then, the id you get when reading the file is a char* and the compiler will complain when trying to assign it to llegada[i].id.
For this to work, you need to make a string copy using the string.h library.
The following code works.
#include <stdio.h>
#include <string.h>
#define MAX 100
#define IDLEN 80
struct vehiculos{
float peso;
int hora;
char id[IDLEN];
int ferry;
};
void asignar(struct vehiculos llegada[MAX], FILE* input_file) { // Here i have more parameters, but they are useless in this question...
char id[IDLEN];
int i;
i=0;
while(!feof(input_file)){
fscanf(input_file,"%f %d %s %d",&llegada[i].peso,&llegada[i].hora,id,&llegada[i].ferry);
strcpy(llegada[i].id , id);
i++;
}
}
int main(){
struct vehiculos llegada[MAX];
FILE *entrada;
entrada = fopen("proy1.txt","r");
asignar(llegada,entrada);
printf("%s\n",llegada[0].id);
return 0;
}
First, you declared id as an int instead of char*.
Now, when declaring a pointer, some compilers assign null to it, and that is your case.
When you do this: llegada[i].id = id; it dosen't actually assign the string to the pointer, instead you should allocate space (malloc or similar) and use strcpy.
After creating your struct with null pointer, you are trying to print it. All "flat" members such as int will be printed just fine, but your string, as it is a pointer will print nothing, so printf("%s", llegada[i].id); won't do a thing
Rather than statically declaring id, you can also allocate space for it as needed. Below is an example that shows the use of fgets and sscanf to handle reading and parsing each line read. It has several advantages over fscanf (most notably here allowing you to read and allocate id as needed). Let me know if you have questions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
#define MAXL 256
struct vehiculos {
float peso;
int hora;
char *id;
int ferry;
};
void asignar (struct vehiculos *llegada, FILE *fp, int *idx)
{ // Here i have more parameters, but they are useless in this question...
char line[MAXL] = {0};
char idbuf[MAXL] = {0};
while (fgets (line, MAXL, fp)) {
sscanf (line, "%f %d %s %d", &llegada[*idx].peso, &llegada[*idx].hora,
idbuf, &llegada[*idx].ferry);
llegada[*idx].id = strdup (idbuf);
(*idx)++;
}
// while (!feof (input_file)) {
// fscanf (input_file, "%f %d %s %d", &llegada[i].peso, &llegada[i].hora,
// id, &llegada[i].ferry);
// llegada[i].id = id;
// i++;
// }
}
int main (int argc, char **argv)
{
FILE *entrada = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!entrada) {
fprintf (stderr, "error: failed to open input for reading.\n");
return 1;
}
int i, n = 0;
struct vehiculos llegada[MAX] = {{0,0,NULL,0}};
asignar (llegada, entrada, &n);
if (entrada != stdin) fclose (entrada);
for (i = 0; i < n; i++)
printf (" llegada[%2d] peso: %3.2f hora: %2d id: %8s ferry: %d\n",
i, llegada[i].peso, llegada[i].hora, llegada[i].id, llegada[i].ferry);
for (i = 0; i < n; i++)
free (llegada[i].id);
return 0;
}
Sample Input
$ cat dat/vehiculos.txt
6.80 4 sal_135 2
8.20 3 jim_023 4
5.45 5 sam_101 6
6.75 3 bil_002 16
Example Output
$ ./bin/struct_no_alloc dat/vehiculos.txt
llegada[ 0] peso: 6.80 hora: 4 id: sal_135 ferry: 2
llegada[ 1] peso: 8.20 hora: 3 id: jim_023 ferry: 4
llegada[ 2] peso: 5.45 hora: 5 id: sam_101 ferry: 6
llegada[ 3] peso: 6.75 hora: 3 id: bil_002 ferry: 16

C: Using strcpy to transfer one struct element to an array

Okay, so we're supposed to prompt a user to enter 25000 lines of text.
Each line contains three integers each. We are then to pass the third integer in that line to another struct, and connect each integer until you have 25000 interconnected integers.
Here's what I've tried:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct graph{
int begin;
int end;
int cost;
} PathEdge;
int comp_fcn(const void *a, const void *b) {
return ((PathEdge *) a)->cost - ((PathEdge *) b)->cost;
}
int main(void)
{
int nlines,i;
char r;
int ecost,ebegin,eend;
scanf("%d",&nlines);
PathEdge edges[nlines+1];
for(i=0;i<nlines;i++)
{
scanf("%d, %d, %dn",&ebegin, &eend, &ecost);
edges[i].begin = ebegin;
edges[i].end = eend;
edges[i].cost = ecost;
struct town
{
struct town *north;
int name[25000];
};
struct town *root, *current;
root = malloc(sizeof(struct town));
root->north = NULL;
strcpy (root->name,ecost);
current = malloc(sizeof(struct town));
current->north = root;
strcpy (current->name,ecost);
}
printf("Please enter a node that you want to examine. If you want to exit, please press 'X'.n");
scanf("%c",&r);
switch(r)
{
case 'X':
case 'x':
printf("You entered a wrong value. Gomen. Try againn.");
break;
default:
if((0<r)&&(r<25000))
{
printf("You have accessed node %dn",r);
printf("Its neighboring nodes are %dn",edges[r].cost);
printf("Its neighboring nodes are %dn",edges[i].cost);
}
else
{
printf("Invalid input again. Please do try again. Thanksn");
}
break;
}
return 0;
}
And there are warnings...
"passing argument 1 of strcpy from incompatible pointer type"
"passing argument 2 of strcpy makes pointer from integer without a cast"
expected char*__ restrict __ but argument is of type 'int'
plus when I inputted that 25000 lines of text, segmentation fault happens. Please help. Thank you!
strcpy is for copying strings (i.e. zero terminated byte char "arrays"), you maybe should use memcpy instead.
Or if you just want to assign a single integer to one element in the array, use plain assignment:
current->name[someIndex] = ecost;
Or, maybe you intend that thename member should be a string? Then you should be using an array of characters and not integers. And you need to convert integer values to strings, using e.g. sprintf:
sprintf(current->name, "%d", ecost);
you can convert the integer to string using itoa and copy the string into root->name.
char str[20];
itoa(ecost, str, 10);
strcpy(root->name, str);
You did not state your exact issue so I am assuming you are overwhelmed and in that case you should try partitioning your implementation into functions so that you can work on isolated problems instead of a web of interconnected problems.
Here is one example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct graph {
int begin;
int end;
int cost;
} PathEdge;
const char * GenerateInput()
{
static char local[2000];
static int last = 0;
int a, b, c;
a = last++;
b = last++;
c = last++;
sprintf_s(local, 2000, "%i %i %i", a, b, c);
return local;
}
void PathEdgeInitializeFromString(PathEdge * edge, const char * str)
{
sscanf_s(str, "%d %d %dn", &edge->begin, &edge->cost, &edge->end);
}
void QueryAndPrint(PathEdge * edges, int edges_n)
{
printf("Enter a number from 1 to %i: ", edges_n);
int index = 0;
scanf_s("%i", &index);
--index;
if (index < 0 || !(index < (edges_n)))
printf("Error");
else
printf("%i, %i, %i\n", edges[index].begin, edges[index].cost, edges[index].end);
}
int main() {
PathEdge edges[25000];
for (int i = 0; i < 25000; ++i)
{
const char * line = GenerateInput();
PathEdgeInitializeFromString(edges + i, line);
}
QueryAndPrint(edges, 25000);
return 0;
}

Unable to retrieve data from array of character inside structure

I am using below code in one file
file 1
//structure is global
struct abc
{
char var;
char *a[5];
}*p;
struct abc q;
int main()
{
char t[] = "sample"
p = &q;
p->a[0] = &t[0];
p->var = 10;
printf("var = %d, string = %s\n", p->var, p->a[0]);
func();
exit(0);
}
But if I try to access the structure member (a[]) in func() that is in another file I don't get the data that is assigned in another file (above).
file2
int fucn()
{
char var1;
var1 = p->var;
printf("var1 = %d\n", var1);
//since i am unable to copy p->a[0] to some other string i am trying to print the contents of p->a[0].
printf("a = %s\n", p->a[0]);
}
program crashes executing the second printf but I can print the content of p->var which is assigned in some other file.
Something like below is what you need.
An include file.
prompt> cat foo.h
struct abc {
char var;
char *a[5];
};
extern struct abc *p;
main function
prompt> cat main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "foo.h"
struct abc q, *p;
extern int func();
int
main()
{
p = &q;
/*
* Using strcpy after allocating memory.
*/
p->a[0] = malloc(strlen("zero") + 1);
strcpy(p->a[0], "zero");
/*
* strdup is equivalent to malloc and strcpy
*/
p->a[1] = strdup("one");
p->a[2] = "two";
p->a[3] = "three";
p->a[4] = "four"
p->var = 10;
printf("main var = %d, string = %s %s %s %s %s\n",
p->var, p->a[0], p->a[1], p->a[2], p->a[3], p->a[4]);
func();
return(0);
}
func function
prompt> cat func.c
#include <stdio.h>
#include "foo.h"
int
func()
{
int r;
r = printf("func var = %d, string = %s %s %s %s %s\n",
p->var, p->a[0], p->a[1], p->a[2], p->a[3], p->a[4]);
return(r);
}
Compile and run
prompt> gcc mainc.c func.c
prompt> a.out
main var = 10, string = zero one two three four
func var = 10, string = zero one two three four

Resources