beautiful world
beautiful world

Reputation: 41

How to get the last char from a string

I want to get the weight and the object in a list string( in this example I want to get the integer 501 and the string "kg bag of sugar". But I don't know-how may string after the integer. but I do know how many spaces before and after the integer (that is why I do +3 since there are 2 spaces before integer and 1 space at the end). I got a segmentation fault in my code.

Here is an example of what I am trying to do.

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

/* get the weight and the object */
int main(void) {   
    char line[50] = "  501 kg bag of sugar"; //we don't know how many char after integer 
    char afterint[50];
    long int weight, weight2;
    int lenofint;
    sscanf(line, "%ld", &weight);
    weight2 = weight;
    while (weight2 != 0) {
        weight2 = weight2 / 10;
        lenofint++;
    }
    
    afterint[0] = line[lenofint + 3]; // +3 since there are 2 spaces before integer and 1 space at the end
    //printf("%c", afterint);
    for (int j = 1; j < (strlen(line) - lenofint - 3); j++) {
        afterint[j] = afterint[j] + line[j + lenofint + 3];
    }
    printf("%s", afterint);
}

Upvotes: 0

Views: 106

Answers (2)

WhozCraig
WhozCraig

Reputation: 66194

Stop hard coding offsets and making this hard on yourself. The scanf family of functions includes an option, %n that will tell you how many characters have been processed in the scan up until that point. From there you can skip over whitespace and proceed to the remainder of your label.

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char line[50] = "  501 kg bag of sugger";
    long int weight;
    int count;

    if (sscanf(line, "%ld%n", &weight, &count) == 1)
    {
        char *suffix = line+count;
        while (*suffix && isspace((unsigned char)*suffix))
            ++suffix;

        puts(suffix);
    }
}

Output

kg bag of sugger

As a bonus, by using this method you also get error checking. Note the check for return result from sscanf, which indicates the number of successful argument parses. If that isn't 1, it means whatever was in the buffer lead position could not be parsed successfully as %ld (long int), and therefore the rest is pointless.

Upvotes: 2

ilkkachu
ilkkachu

Reputation: 6517

You can use strtol() to read the number and get a pointer to the point in the string after the number. It would then point to kg bag of sugar. That way you don't need to do any back-calculations from the number. In any case, the number could have leading zeroes or such, so you can't know the length in characters from the numerical value anyway.

Then just skip over the whitespace from the pointer you got from strtol.

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
    char *foo = "  501 kg bag of sugar";
    char *thing = NULL;
    int weight = 0;
    weight = strtol(foo, &thing, 10);
    while (isspace(*thing)) {
        item++;
    }
    printf("weight: %d thing: %s\n", weight, thing);
}

Alternatively, I suppose you could do something like sscanf(foo, "%d %100c", &weight, buffer); to get both the number and the following string. (I'll leave it to you to pick a saner conversion than %100c.)

Upvotes: 1

Related Questions