UcfKnight
UcfKnight

Reputation: 55

How do I convert a string to a numeric value in C?

It would be better If I show you guys an example of what my program is supposed to do.

Input:

3
Double Double End
Triple Double End
Quadruple Double Triple End

Output:

4
6
24

So, the first sentence Double Double means 2*2 and Triple Double means 3*2 and so on.

The word End signifies the end of the string.

It looks very simple, but I have no idea how to work with strings and give them a value and continue on from there.

Here is all I have done so far:

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

int main()
{

    int num_of_orders,i,j;
    char orders[25];
    char str1[25] = "Double";
    char str2[25] = "Triple";
    char str3[25] = "Quadruple";

    scanf("%d", &num_of_orders);

    for (i=0; i<num_of_orders+1; i++){
        scanf("%s", orders);
    }

    return 0;
}

Upvotes: 0

Views: 117

Answers (4)

Miquel Perez
Miquel Perez

Reputation: 455

When it comes to reading the input, you can use strtok with a " " as a parameter to delimite the words you're reading from the input. This is a function filling all of the words read on the input into an array of strings:

PARAMETERS:

char **words: array of strings where you will store all of the words read in the input

char *input: the input you read (i.e. "Double Double end")

char *s: the delimiter you'll use to read words in the input (i.e. " ", "\n")

void getWords(char **words, char *input, char *s){

    *words = strtok(str, s); 
    while(*words){
        words++;
            *words = strtok(NULL, s); 
    }               
    words++;
    *words=NULL;  //last element will point to NULL
}

Once you have read the words from the input, and filled them inside an array of strings, you could do something like this to calculate the output:

int calculate(char **words){

  int result = 1;

  while(*words){

    if (strcmp(*words, "Quadruple") == 0){

     result *= 4;

    }else if (strcmp(*words, "Triple") == 0){

      result *= 3;

    }else if (strcmp(*words, "Double") == 0){

      result *= 2;

    }else if (strcmp(*words, "End") == 0){

       return result;

    }

          words++;

  }    

}

Note that you need to correctly initialize the parameters you're passing before calling those functions. Otherwise, it may cause a Segmentation Fault.

Upvotes: 1

nalzok
nalzok

Reputation: 16107

Don't forget the fact that the multiplication of integers is commutative:

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

int main(void)
{
    int num_of_orders, i;
    char orders[25];
    int result;
    char *ptr;

    scanf("%d", &num_of_orders);
    getchar(); // To comsume '\n'

    for (i = 0; i < num_of_orders; i++)
    {
        fgets(orders, sizeof orders, stdin);
        result = 1;
        ptr = orders;
        while(ptr = strstr(ptr, "Double"))
        {
            result *= 2;
            ptr++;
        }
        ptr = orders;
        while(ptr = strstr(ptr, "Triple"))
        {
            result *= 3;
            ptr++;
        }
        ptr = orders;
        while(ptr = strstr(ptr, "Quadruple"))
        {
            result *= 4;
            ptr++;
        }
        printf("%d\n", result);
    }
    return 0;
}

What a trivial approach!

Note that strtok() is destructive, namely it will modify order, which can cause some problems if you want to use it later. Also, I think programs using strtok() are less readable. So it might be better to avoid it when possible.

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84521

There are a number of ways to approach this problem, as indicated by the variety of answers. There is often no one right answer for how to approach a problem in C. The standard library provides a variety of tools that allow you to craft a number of solutions to just about any problem. As long as the code is correct and protects against error, then the choice of which approach to take largely boils down to a question of efficiency. For small bits of example code, that is rarely a consideration.

One approach to take is to recognize that you do not need the first line in your data file (except to read it/discard it to move the file-position-indicator to the start of the first line containing data.)

This allows you to simply use a line-oriented input function (fgets or getline) to read the remaining lines in the file. strtok then provides a simple way to split each line into words (remembering to strip the '\n' or discard the last word in each line). Then it is a small matter of using strcmp to compare each word and multiply by the correct amount. Finally, output the product of the multiplication.

Here is one slightly different approach to the problem. The program will read from the filename given as the first argument (or from stdin by default):

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

enum { MAXC = 64 };

int main (int argc, char **argv) {

    char buf[MAXC] = "";    /* line buffer */
    char *delims = " \n";   /* delimiters  */
    int idx = 0;            /* line index  */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file pointer */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    while (fgets (buf, MAXC, fp)) {     /* read each line */
        if (!idx++) continue;           /* discard line 1 */
        char *p = buf;
        size_t len = strlen (p);        /* get length     */
        int prod = 1;
        if (len && buf[len-1] == '\n')  /* check for '\n' */
            buf[--len] = 0;             /* remove newline */
        printf (" %s", buf);  /* output buf before strtok */

        /* tokenize line/separate on delims */
        for (p = strtok (p, delims); p; p = strtok (NULL, delims))
        {   /* make comparson and multiply product */
            if (strcmp (p, "Double") == 0)    prod *= 2;
            if (strcmp (p, "Triple") == 0)    prod *= 3;
            if (strcmp (p, "Quadruple") == 0) prod *= 4;
        }
        printf ("  =  %d\n", prod);     /* output product */
    }

    if (fp != stdin) fclose (fp);  /* close file if not stdin */

    return 0;
}

Use/Output

$ ./bin/dbltrpl <../dat/dbltrpl.txt
 Double Double End  =  4
 Triple Double End  =  6
 Quadruple Double Triple End  =  24

Look it over and let me know if you have questions.

Upvotes: 2

Ahmed Akhtar
Ahmed Akhtar

Reputation: 1463

You will have to use the methods from the string.h library, such as: strcmp(to compare two strings), strcpy(to copy one string to another) etc. which are generally used when dealing with strings manipulation in c.

Since, we do not know the size of the results array at compile time, we will have to allocate memory to it dynamically. For this purpose I have used malloc and free.

Here is the code to do that:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{

    int num_of_orders, i, j;
    char orders[25];
    char str1[25];
    strcpy(str1,"Double");
    char str2[25];
    strcpy(str2,"Triple");
    char str3[25];
    strcpy(str3,"Quadruple");

    scanf("%d", &num_of_orders);
    getchar();

    int *results = malloc(num_of_orders*sizeof(int));

    for (i=0; i < num_of_orders; i++)
    {
        results[i] = 1;
        strcpy(orders,"");
        while(strcmp(orders,"End") != 0)
        {
         scanf("%s", orders);
         getchar();

         if(strcmp(orders,str1)==0)
          results[i] *= 2;
         else if(strcmp(orders,str2) == 0)
          results[i] *= 3;
         else if(strcmp(orders,str3)==0)
          results[i] *= 4;
        }
    }

    for(i = 0; i < num_of_orders; i++)
     printf("%d\n", results[i]);

    free(results);

    return 0;
}

Note: This program uses strcmp, which does case-sensitive comparison. If you want case-insensitive comparison, then use strcasecmp instead.

Upvotes: 0

Related Questions