2

I have a problem on printing the arrays content. Every time I want to print them I get a segmentation fault(look at the commented code). Why is that?

#include <stdio.h>
int main(int argc, char* argv[])
{
    char const* const fileName = argv[1];
    FILE* file = fopen(fileName, "r");
    char line[256];
    char str1[10], str3[10];
    int str2[10], str4[10];
    while (fgets(line, sizeof(line), file)) {
        printf("The Full Line is: %s", line);
        sscanf(line,"%s -> %s", str1,str3);
        printf("First is: %s \n", str1);
        printf("Thirs is : %s\n", str3);
    }
    fclose(file);
//    printf("%s", str1[0]);
//   for (int i=0; i<4; i++){
//       printf("This is it!!! %s ", str1[i]);
//    }
    return 0;
}

The input text file contains:

main+0x20 -> main+0x10
function1 -> function2+0x20
function2+0x34 -> function3

or more complex one:

Function2+0x22 -> main+0x92
main -> main+0x22
Function2 -> vuln+0x12
main+0x86 -> Function1
main+0x86 -> main+0x92
Function1+0x12 -> Function2+0x22
func1+0x10 -> main+0x76
dummya -> func1+0x10
main+0x6a -> main+0x76
main+0x6a -> func1
main+0x76 -> main+0x86
main+0x22 -> main+0x3a
main+0xa2 -> main+0xae
func1 -> dummya
func1 -> func1+0x10
main+0x92 -> main+0xa2
main+0x3a -> main+0x52
main+0x52 -> main+0x6a

Can I put this values into a 2D array. And then print it. If yes how to do it?

I want an output like this:

Array1[1]= main
Array2[1]=0x20 //in int
Array3[1]=main
Array4[1]=0x10 //in int

Array1[2]=Function1
Array2[2]=0 //in int
Array3[2]=Function2
Array4[2]=0x20 //in int

Array1[3]=Function2
Array2[3]=0x34 //int
Array3[3]=Function3
Array4[3]=0
//Continue until EOF
1
  • 2
    Did you pass an argument? Did fopen() succeed? Did sscanf() scanned expected elements? In other words, start debugging. Commented Aug 1, 2016 at 11:09

3 Answers 3

3

Use of %s assume pointer to char array ending null symbol. But you give char instead pointer to char.

If you need one symbol - you should use %c:

printf("%c", str1[0]);
for (int i=0; i<4; i++){
    printf("This is it!!! %c ", str1[i]);
}

If you need string with offset - you should use pointers:

printf("%s", &str1[0]);
for (int i=0; i<4; i++){
    printf("This is it!!! %s ", &str1[i]);
}

See printf reference.

EDIT1:

Solved...

#include <stdio.h>
#define MAX_LINE_CNT 3
int main(int argc, char* argv[])
{
    char const* const fileName = argv[1];
    FILE* file = fopen(fileName, "r");
    char line[256];
    char i, cnt = 0;
    char str1[MAX_LINE_CNT][10], str3[MAX_LINE_CNT][10], * tmp;
    int arr2[MAX_LINE_CNT], arr4[MAX_LINE_CNT];
    while (fgets(line, sizeof(line), file)) {
        tmp = strstr(line," -> ");
        arr2[cnt] = 0; arr4[cnt] = 0;
        sscanf(line,"%[^+ ]%x%*s", str1[cnt],&arr2[cnt]);
        sscanf(tmp," -> %[^+ ]%x%*s", str3[cnt],&arr4[cnt]);
        //cnt++;
        if (++cnt >= MAX_LINE_CNT) break;
    }
    fclose(file);
    for (i = 0; i < cnt; i++) {
        printf("Array1[%d] %s \n", i+1, str1[i]);
        printf("Array2[%d] %x \n", i+1, arr2[i]);
        printf("Array3[%d] %s \n", i+1, str3[i]);
        printf("Array4[%d] %x \n", i+1, arr4[i]);
    }
    return 0;
}

EDIT2:

It is strictly recomended to read chux's answer and c/c++ reference for understand what you doing and what the hell is going after compiling.

Sign up to request clarification or add additional context in comments.

12 Comments

It works, but now instead of showing for example main+0x20 as the member of first line in the array, it shows like m, a , i ,n ......Why it is like that?
@SamaAzari, evidently you have tried to use %c in printf, so you just print first four symbols from char arrray str1. Explain please, what you need at output?
I wanted the output to be like : main and another array have 0x20 and another one have main and another one 0x10 and it continue per line so 4 array contain the name and a value (e.g. function+0x20) I think I have to do it with two 2D array.
You could for deeper insight explain what printf does with the supplied value corresponding to a %s conversion specifier, in the attempt to print a string.
Ah I see you did not read from the file(in the solved link) , but copied the values to a char. Can we read it from file in the solved link? And the one which you put here does not work properly But the one in the solved link does work, however it can not read from a file.
|
2

Every time I want to print them I get a segmentation fault(look at the commented code). Why is that?

A) Code did not use protection. Notice that when reading data into str1, should the text length exceed 9, code will cause undefined behavior (UB) as str1[10], as a string can only hold up to 9 characters and a null character.

B) Code did not check the result of sscanf(). Unless 2 fields were scanned, printf("Thirs is : %s\n", str3); will cause UB as it could print an uninitialized character array.

// problematic code

// text input "function2+0x34 -> function3\n"
while (fgets(line, sizeof(line), file)) {  
  char str1[10], str3[10];
  sscanf(line,"%s -> %s", str1,str3);
  printf("First is: %s \n", str1);
  printf("Thirs is : %s\n", str3);

How to fix?

A) Limit input into destination arrays. 9 is the maximum character width to read.

  sscanf(line,"%9s -> %9s", str1,str3);

B) Check sscanf() results

  if (sscanf(line,"%9s -> %9s", str1,str3) != 2) {
    fprintf(stderr, "Scan failure\n");
    return -1;
  }

C) Notice that array str1[] and others may be too small. Increase as needed.

Can I put this values into a 2D array. And then print it. If yes how to do it? I want an output like ...

Of course code can, but this is another question that needs greater detail on OP's goal and really should be one that OP attempts first.

Hint: look into sscanf() format specifiers "%[]", "%n" and "%x"

If still having trouble, some untested code to scan str1[] ...

char f[100]; unsigned addr;
int cnt = sscanf(str1, "%99[^+]+%x", f, &addr);
if (cnt == 1) puts("Only first field found");
else if (cnt == 2) puts("Both fields found");
else puts("Unexpected input");

Comments

1

There are many functions that can be checked for success or failure.
This defines SIZE as 4 but that can be increased as needed.
char str1[SIZE][40] allows up to 4 strings with up to 40 characters each.
The first step is to separate the two initial substrings. Using a scanset, %39[^-] will scan up to 39 characters (prevent writing too many characters into the array memory) and capture all characters that are not -.
strchr tests if the substring contains a + and the substring is parsed as appropriate.

#include <stdio.h>
#include <string.h>

//maximum lines to process
#define SIZE 4

int main(int argc, char* argv[])
{
    char line[256];
    char str1[SIZE][40], str3[SIZE][40];
    char sub1[40], sub3[40];
//        char sub1[SIZE], sub3[SIZE];   //mistake on this line
    int str2[SIZE], str4[SIZE];
    int each = 0;
    int result = 0;
    int loop = 0;
    FILE* file = NULL;

    //check for correct arguments
    if ( argc != 2) {
        printf ( "syntax is program filename\n");
        return 1;
    }

    //check for successful file opening
    if ( ( file = fopen(argv[1], "r")) == NULL) {
        printf ( "could not open file %s\n", argv[1]);
        return 2;
    }

    while (fgets(line, sizeof(line), file)) {//loop through the file one line at a time
        printf("The Full Line is: %s", line);
        //sscanf the two sub strings
        //sscanf returns number of items scanned so success will be 2
        if ( ( result = sscanf(line,"%39[^-] -> %39[^\n]", sub1,sub3)) == 2) {
            printf("First is: %s \n", sub1);
            printf("Thirs is : %s\n", sub3);
            //is there a + in the substring
            if ( ( strchr ( sub1, '+')) != NULL) {
                //get the two values
                if ( ( result = sscanf ( sub1, "%39[^+]+ 0x%x",str1[each], &str2[each])) != 2) {
                    printf ( "problem parsing sub1 + %s\n", sub1);
                    continue;
                }
            }
            else {// no +
                str2[each] = 0;
                //get the one value
                if ( ( result = sscanf ( sub1, "%39s",str1[each])) != 1) {
                    printf ( "problem parsing sub1 %s\n", sub1);
                    continue;
                }
            }
            //is there a + in the substring
            if ( ( strchr ( sub3, '+')) != NULL) {
            //if ( ( sub3[strcspn ( sub3, "+")]) < strlen ( sub3)) {
                //get the two values
                if ( ( result = sscanf ( sub3, "%39[^+]+ 0x%x",str3[each], &str4[each])) != 2) {
                    printf ( "problem parsing sub3 + %s\n", sub3);
                    continue;
                }
            }
            else {
                str4[each] = 0;
                //get the one value
                if ( ( result = sscanf ( sub3, "%39s",str3[each])) != 1) {
                    printf ( "problem parsing sub3 %s\n", sub3);
                    continue;
                }
            }
            each++;
            if ( each >= SIZE) {
//                if ( each > SIZE) {   //mistake on this line
                break;
            }
        }
        else {
            printf ( "trouble parsing %s\n", line);
        }

    }
    fclose(file);

    for ( loop = 0; loop < each; loop++) {
        printf("Array[%d]=%s\n", loop + 1, str1[loop]);
        printf("Array[%d]=0x%x\n", loop + 1, str2[loop]);
        printf("Array[%d]=%s\n", loop + 1, str3[loop]);
        printf("Array[%d]=0x%x\n\n", loop + 1, str4[loop]);
    }
    return 0;
}

2 Comments

give me wrong output : The Full Line is: main+0x20 -> main+0x10 First is: +0x10 Thirs is : main+0x10 problem parsing sub1 + +0x10 The Full Line is: function1 -> function2+0x20 First is: tion2+0x20 Thirs is : function2+0x20 problem parsing sub3 + functionfunctionfuncti Array[1]=tion3 Array[1]=0x0 Array[1]=functionf Array[1]=0x0
Apparently it misses first function (some how jump). and then for second function it misses the func(just print "tion2")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.