How to read integers with sscanf separated by symbols in C? - c

so I have a string with the following value
[7, 8]
Now I wan't to store each value (only the numbers) in a 2D array [1][2].
I'm pretty sure using sscanf is the best way to do this, but how do I tell sccanf to only read the integers?
Thanks in advance

sscanf("[%d,%d]", Array[a][b], Array[c][d]);

You might get an entire line using getline(3), or fgets(3) if your system don't have getline.
Then you can parse that line manually. You might indeed at some point use sscanf(3) (and you could use %n and always test the return count from sscanf), but you could use strtol(3) (its endptr argument is handy!), etc.
Always test the return count given by sscanf, fscanf, scanf !
Some people might recommend strtok(3) which I dislike because it is stateful and non-reentrant.
BTW, 2D arrays are tricky in C (and I recommend avoiding them and use only 1D arrays). You might dynamically allocate some struct (that you previously declare) ending with a flexible array member.

I don`t if I am understanding your Problem. But I tried.
Quick n dirty. Maybee this help.
for(int i =1; i++; i =< (sizeof(array1D)/arraydatatype) )
{
array2D[i-1][i-1] = array1D[i-1];
array2D[i-1][i-1] = array1D[i];
}
i = 0;
j = 0;
while (i < arraysize)
{ array2D [j][0] = array1D [i];
array2D [j][1] = array1D [i+1];
j++;
i+=2;
}
scanf is only for reading from console. But you have already an Array?! If you have a string you can work with strncpy or something..

Related

Why this is not working? Strings in C. If always true. WHY?

Please help me.
I don't know why this program is not working.
Sorry, but I needed to post whole code so it can be understanded clearly.
I tried to put str in txt file and then read it again and it is the same problem.
Also, I tried changing pointers with some other and then sompareing them and also the samo problem.
Arguments of program are:
1) txt file - with something like this - xyxxyyyxyxxyxyyxyxyxyyyyxxxx...
2) number - example - 2 - means that i need to group symbols in pairs
Output should be probaillity of any combination of x and y (xx,yy,xy,yx - for group of 2).
example:
p(xx)=0.4
p(yy)=0.1
p(yx)=0.5
p(xy)=0
BUT!
this is ALWAYS TRUE:
if (str==lista[i])
WHY?
I am struggling with it for hours. :(
I tried what others suggested:
Look at this:
http://i.imgur.com/SL1L8hc.jpg and
http://i.imgur.com/QwZGdgM.jpg
Weirdest one:
http://i.imgur.com/BIeLXOu.gif
WHOLE CODE:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
typedef char * string;
int main(int argc, char *argv[]){
if (argc<3) {
return -1;
}
FILE *ul;
int mode,i,dane,j,razl;
char *str;
int brojac=0;
string lista[1000];
int pomlis[1000];
ul=fopen(argv[1],"r");
fseek(ul,0,SEEK_SET);
if (!ul){
return 1;
}
for (i=0;i<1000;i++){
lista[i]="nist";
pomlis[i]=0;
}
mode=atoi(argv[2]);
str=(char*)malloc(mode+1);
brojac=0;
razl=0;
while (fgets(str,sizeof(char)*mode+1,ul)!=NULL){
dane=0;
// printf("%s ",str); //da bi printao u konzolu
brojac++;
for (i=0;i<=razl;i++){
if (str==lista[i]){
pomlis[i]++;
dane=1;
}
}
if (dane==0){
if (lista[i]=="nist") i--;
lista[i+1]=str;
pomlis[i+1]=1;
razl++;
}
}
for (i=1;i<=razl;i++){
printf("p(%s)=%f\n",lista[i],pomlis[i]/((double)brojac));
}
fclose(ul);
return 0;
}
I tried all suggestions in the comments and nothing works. Does anyone knows the answer?
First of, sizeof(char) is 1 by definition. It doesn't make the code more readable.
The line
fgets(str,sizeof(char)*mode+1,ul);
reads into char *str which is allocated in
str=(char*)malloc(sizeof(char)*mode);
Which should omit the cast, and is too small to hold everything fgets() writes to it (by the +1 '\0').
In addition:
printf("p(%s)=%d\n",lista[i],pomlis[i]/brojac);
pomolis[i] and brojac are both integers, therefore the division will not return a fraction (float/double) but an integer again (most likely zero in your program).
Thank you all, edited, but, can I get answer? Why I am getting minuses on question if no one knows answer?
Well, try replacing the line
if (str==lista[i]){
with
if (!strncmp(str, &lista[i], mode){
and remove the line
fgets(str,sizeof(char)*mode+1,ul);
in the body of the while-loop (you are already calling fgets() in the while condition, don't call it twice)
Your code has many problems. I suggest reading about pointers, memory allocation and how strings work in c. Because of your typedef char * string i suppose you must be coming from a higher language then c. Forget that knowledge, you'll have big problems if you try to apply it here.
I've made it work, but I will not post the working code here, as I'm not interested in doing anyone's homework. I'll try to teach you what your problems are.
Your first problem is here:
for (i=0;i<1000;i++){
lista[i]="nist";
pomlis[i]=0;
}
Assigning "nist" to char * assigns the address of a constant string "nist" to the pointer. As the string is constant, if you later try to change something in it, you will fail.
You should use malloc, which allocates memory you can write to:
for (i=0;i<1000;i++){
lista[i]=(char*) malloc(5);
pomlis[i]=0;
}
Next, as others have explained, using == is quite different then using strncmp. You should use:
if (strcmp(str, lista[i])==0){
pomlis[i]++;
dane=1;
}
The next part makes absolutely no sense:
if (dane==0){
if (lista[i]=="nist") i--;
lista[i+1]=str;
pomlis[i+1]=1;
razl++;
}
First you're comparing to another pointer to constant string (note that "nist" you've initialized to doesn't have to be the same "nist" you have here). I really have no idea what you're trying to accomplish using i here.
I wrote it like this:
if (dane==0){
memcpy(lista[razl],str, sizeof(str));
pomlis[razl]=1;
razl++;
}
Try to understand this.
Finally, your for loops go to the limit i<=razl. As arrays are zero initialized, you should break before i hits razl.
if (str==lista[i])
Now, str and lista[i] are of type char*. That is they are pointers. In which case the == operator tests for equality of the pointer addresses. So, if this == operator evaluates true then the two pointers have the same address.
If you want to compare the value of the string then you must use strcmp().

Using snprintf to print an array? Alternatives?

Is it at all possible to use snprintf to print an array? I know that it can take multiple arguments, and it expects at least as many as your formatting string suggests, but if I just give it 1 formatting string and an array of values, will it print the entire array to the buffer?
The reason I ask, is because I am modifying source code, and the current implementation only supported one value being placed in a string, but I am modifying it to support an array of values. I want to change the original implementation as little as possible.
If this doesn't work, is there another way someone would recommend to do this? Should I just suck it up and use a for loop (how well would that really work without stringbuffers)?
Essentially: What would be the best way to get all of the values from an array of doubles into the same string for a return?
No, there's no formatting specifier for that.
Sure, use a loop. You can use snprintf() to print each double after the one before it, so you never need to copy the strings around:
double a[] = { 1, 2, 3 };
char outbuf[128], *put = outbuf;
for(int = 0; i < sizeof a / sizeof *a; ++i)
{
put += snprintf(put, sizeof outbuf - (put - outbuf), "%f ", a[i]);
}
The above is untested, but you get the general idea. It separates each number with a single space, and also emits a trailing space which might be annoying.
It does not do a lot to protect itself against buffer overflow, generally for code like this you can know the range of the inputs and make sure the outbuf is big enough. For production code you would need to think about this of course, the point here is to show how to solve the core problem.
I decided to go with this:
int ptr = 0;
for( i = 0; i < size; i++)
{
ptr += snprintf(outbuf + ptr, sizeof(outbuf) - ptr, "%.15f ", values[i]);
}
slightly different, but to the same effect as in #unwind 's solution. I got this idea from the reference page for snprintf()

How to write into a char array in C at specific location using sprintf?

I am trying to port some code written in MATLAB to C, so that I can compile the function and execute it faster (the code is executed very often and it would bring a significant speed increase).
So basically what my MATLAB code does it that it takes a matrix and converts it to a string, adding brackets and commas, so I can write it to a text file. Here's an idea of how this would work for a vector MyVec:
MyVec = rand(1,5);
NbVal = length(MyVec)
VarValueAsText = blanks(2 + NbVal*30 + (NbVal-1));
VarValueAsText([1 end]) = '[]';
VarValueAsText(1 + 31*(1:NbVal-1)) = ',';
for i = 1:NbVal
VarValueAsText(1+(i-1)*31+(1:30)) = sprintf('%30.15f', MyVec(i));
end
Now, how can I achieve a similar result in C? It doesn't seem too difficult, since I can calculate in advance the size of my string (char array) and I know the position of each element that I need to write to my memory area. Also the sprintf function exists in C. However, I have trouble understanding how to set this up, also because I don't have an environment where I can learn easily by trial and error (for each attempt I have to recompile, which often leads to a segmentation fault and MATLAB crashing...).
I hope someone can help even though the problem will probably seem trivial, but I have have very little experience with C and I haven't been able to find an appropriate example to start from...
Given an offset (in bytes) into a string, retrieving a pointer to this offset is done simply with:
char *ptr = &string[offset];
If you are iterating through the lines of your matrix to print them, your loop might look as follow:
char *ptr = output_buffer;
for (i = 0; i < n_lines; i++) {
sprintf (ptr, "...", ...);
ptr = &ptr[line_length];
}
Be sure that you have allocated enough memory for your output buffer though.
Remember that sprintf will put a string-terminator at the end of the string it prints, so if the string you "print" into should be longer than the string you print, then that won't work.
So if you just want to overwrite part of the string, you should probably use sprintf to a temporary buffer, and then use memcpy to copy that buffer into the actual string. Something like this:
char temp[32];
sprintf(temp, "...", ...);
memcpy(&destination[position], temp, strlen(temp));

Memory issue in my Sub String function in C?

I have this C function which attempts to tell me if a sub string is contained in a string.
int sub_string(char parent [1000], char child [1000]){
int i;
i = 0;
int parent_size = (int) strlen(parent);
int child_size = (int) strlen(child);
char tempvar [child_size];
int res;
res = 1;
while(i<(parent_size - child_size + 1) && res != 0){
strncpy(tempvar, parent + i, child_size);
if(strcmp(tempvar, child)==0){
res = 0;
}
i++;
memset(tempvar, 0, child_size);
}
memset(tempvar, 0, sizeof(tempvar));
return res;
}
Now the strange thing is, when I pass a string "HOME_DIR=/tmp/" and "HOME_DIR" it returns a 0 the first time round, but after I call this function again, it returns a 1 to say it hasn't found it!!
I am guessing this is a memory issue, but I can't tell where, I would appreciate any help on this.
Is there any reason you can't use the strstr function? Otherwise there are some things you should clean up in your code. For starters since you are limiting the length of the arrays coming in to 1000 characters you should use strnlen instead of strlen with a limit of 1000. You should also create you should zero out the tempvar array before you start copying into it. If parent is not null terminated you could run off the end of the array in your while loop. I would also suggest using strncmp and giving a length limit (in general if you are using the C string library you should use the 'n' version of the functions i.e. strnlen instead of strlen so that you put a bounding length on the operation, this helps to protect buffer overflows and potential security holes in your code).
I have noticed some issues with this program:
Use pointers instead of fixed char arrays. This is more space optimal. So your function definition becomes int sub_string(char *parent, int parent_len, char *child, int child_len). Please note that since I pass pointers I also need to pass the length of the string so I know how much to traverse. So now you access your string like so *(parent+i) in a loop.
i<(parent_size - child_size + 1) This condition looks a bit dicey to me. Let's say parent is 100 in len & child is 75. so this expression becomes i<26. Now your loop will terminate when i>26. So tempvar would have the parent_string till index 25. So how does this work again?
One problem is:
char tempvar [child_size];
strcmp below will compare child_size+1 characters (incl. terminating '\0'), therefore its undefined behaviour.
Do you know the C-standard functions strstr and strncmp?
sizeof(tempvar) does not return child_size.

How do we know that a string element in C is uninitialized?

Is there a way to know whether the element in a string in C has a value or not? I have tried using NULL, '', and ' ', but they don't seem to be working. I need to shift the characters down to index 0 without using stdlib functions.
#include <stdio.h>
int main()
{
char literal[100];
//literal[99] = '\0'
literal[98] = 'O';
literal[97] = 'L';
literal[96] = 'L';
literal[95] = 'E';
literal[94] = 'H';
int index = 0;
while(literal[index] != '\0')
{
if(literal[index] == NULL) // does not work
printf("Empty");
else
printf("%c", literal[index]);
++index;
}
getchar();
return 0;
}
No. Since literal has automatic storage, its elements will not be initialized, the values in the array is undefined.
You could initialize every element to something special and check for that value.
e.g. you could change
char literal[100];
char literal[100] = {0};
to initialize every element to 0.
You'd have to change your while loop termination check to
while(index < 100) {
if(literal[index] == 0)
printf("Empty");
...
}
}
That might not be optimal if you need to perform more string manipulation on the array though, as 0 now means empty element and also 'end of string'.
No, you can't do that. This is because it will have a value - there is just no way of knowing what that value is. This is why it is essential to initialise things to known values.
C does not default initialize anything. Therefore the contents in your string are whatever garbage was in that memory by whatever last used it on the stack. You need to explicitly set each literal value to a value that means "unset" to you.
No, there is no way of knowing what value the array has. You can, however, initialize it with a chosen "default" value of your choice and later check against that.
You need to set the end of the string to 0 (zero) or '\0' - C only does this for you automatically for string literals, not local variables on the stack
Try
memset(&literal, 0, 100);
Or just uncomment your line that sets literal at index 99 to '\0'
A c string is just a bunch of memory locations and a convention that '\0' marks the end. There is no compiler enforcement, and no attached meta data (unless you build a structure to provide it).
Every cell in memory, always has a value, so every string always has a value, you just can't guarantee that it is sensible or even that it ends in the allotted space.
Insuring that there is meaningful data in there is your responsibility, which suggests that you should initialize all strings either at declaration time or immediately after allocation. Exception to the rule are rare and are undertaken at your own risk.
No, that is undefined behaviour as the runtime, for all we care could shove in a few binary ASCII characters, you really do not want to get into that. The best way to deal with it is to use a for loop and iterate through it or use calloc which initializes a pointer but sets it to 0.
for (i = 0; i < 100; i++) literal[i] = '\0';
OR
char *literalPtr = (char*)calloc(100, sizeof(char)); // Array of 99 elements plus 1 for '\0'
There is absolutely no guarantee in doing that. Hence it would be classified as undefined behaviour as it is dependent on the compiler and runtime implementation.
Hope this helps,
Best regards,
Tom.

Resources