0

I know that there is a question with the same name, but it didn't work for me. I'm making a home-compiler, returns the words that belongs to a language.

The words to analyze are in this vector:

char *cadenas[]= {"123", "4567L", "5a23", '\0'};

Now I want to enter the words by console, but strings can't be used in C, how can I do it? (Without making a matrix possibly)

void getCadenas(char *cadenas[]){

    printf("Enter cadenas to be analyzed ('z' to scape) \n \n");

    char cadena[15];
    gets(cadena);
    int x=0;

    while(cadena[0]!='z'){
        strcpy(cadenas[x],cadena);
        x++;
        gets(cadena);
    }
}
15
  • 3
    Strings can't be used? Strings can be used. Question could do with a tidy-up, unclear what you want. Commented Aug 5, 2015 at 22:21
  • 3
    Did you look at Taking user input and storing it in an array of strings in C? Does it solve your problem? If not, why not? Commented Aug 5, 2015 at 22:23
  • 2
    Note: I'd expect {"123", "4567L", "5a23", NULL} rather than {"123", "4567L", "5a23", '\0'} Commented Aug 5, 2015 at 22:47
  • 3
    never ever use gets(), it's broken Commented Aug 5, 2015 at 22:57
  • 3
    @Veltas Or simply "". Commented Aug 6, 2015 at 1:05

2 Answers 2

1

If I understand your problem correctly, you would like the user to be able to enter multiple strings, until he/she types z

See if this piece of code helps you out. The strings will be stored in the cadenas array, as requested.

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

#define MAX_CADENAS 100
#define MAX_CADENA_LEN 255
int getCadenas(char **cadenas){
    int x=0;
    char cad[MAX_CADENA_LEN+1];
    printf("Enter cadenas to be analyzed ('z' to scape) \n \n");

    while(x<MAX_CADENAS) {
        scanf("%s", cad);
        if (strcmp(cad,"z")==0)
            break;
        cadenas[x] = malloc(strlen(cad)+1);
        strcpy(cadenas[x], cad);
        x++;
    }
    return x;
}

char *cadenas[MAX_CADENAS];
int main() {
    int num, i;

    num = getCadenas(cadenas);
    for (i=0;i<num; i++) {
        printf("%s\n", cadenas[i]);
    }
}

Note0: the code assumes you know in advance what the maximum number of input strings can be (100). It also assumes a maximum size for each input string (255 characters)

Note1: gets is deprecated. Also, instead of scanf, you might want to use fgets.

Note2: the present code is for illustrative purpose only. It allocates memory for each input string, but it assumes no error occurs in doing so (i.e. it does not check what malloc returns).

Note3: the allocated memory blocks must be freed when not used anymore (hint: cycle through the cadenas array and use free)

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

1 Comment

You should probably just change your answer to use fgets, given that it's not hard to use and is about as long as a scanf call anyway.
0

Assuming you don't mind carrying on with fixed-size strings and arrays, here is your original program modified:

#include <stdio.h>
#include <string.h>
#define MAX_CADENAS 100
#define CADENA_LIMIT 1000

// ...

void getCadenas(char cadenas[MAX_CADENAS][CADENA_LIMIT]){

    printf("Enter cadenas to be analyzed ('z' to scape) \n \n");

    int x;
    for(x=0; x<MAX_CADENAS-1; x++){
        char cadena[CADENA_LIMIT];
        fgets(cadena, CADENA_LIMIT, stdin);
        // fgets will copy the newline character, we don't want that
        int cadenaLength=strlen(cadena);
        if(cadena[cadenaLength-1]=='\n')
            cadena[cadenaLength-1]='\0';
        if(strcmp(cadena, "z")==0) break;
        strcpy(cadenas[x], cadena);
    }
    cadenas[x][0]='\0';
}

// ...

Prefer fgets as you can prevent overflow of the fixed-size strings. Unfortunately it copies the newline as well, so I have code to handle that. The result is an array in the form you originally specified (except it ends with "" which we decided was what you were after in the comments).

You can read arbitrary sized strings in C like in other languages, but you would need to implement it with malloc() and co. Allocating dynamically sized memory is primarily controlled with the functions malloc, calloc, realloc and free. This would make the program unavoidably more complicated. Here is one way of doing this:

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

// ...

char *getCadena(){
    int length=0, capacity=1, character;
    char *cadena=malloc(1); // sizeof(char) is always 1
    while((character=getchar())!=EOF){
        if(character=='\n') break;
        // Add character to string
        length++;
        if(capacity<length){
            capacity*=2;
            cadena=realloc(cadena,capacity);
        }
        cadena[length-1]=character;
    }

    // Add terminator to cadena
    length++;
    if(capacity<length){
        capacity*=2;
        cadena=realloc(cadena,capacity);
    }
    cadena[length-1]='\0';

    return cadena;
}

char **getCadenas(){

    printf("Enter cadenas to be analyzed ('z' to scape) \n \n");

    int length=0, capacity=1;
    char **cadenas=malloc(sizeof(char *));
    for(;;){
        char *cadena=getCadena();
        if(strcmp(cadena,"z")==0){
            free(cadena);
            break;
        }
        // Add pointer to cadenas array
        length++;
        if(capacity<length){
            capacity*=2;
            cadenas=realloc(cadenas,capacity*sizeof(char *));
        }
        cadenas[length-1]=cadena;
    }

    // Add NULL to end of cadenas
    length++;
    if(capacity<length){
        capacity*=2;
        cadenas=realloc(cadenas,capacity*sizeof(char *));
    }
    cadenas[length-1]=NULL;

    return cadenas;
}

void freeCadenas(char **cadenas){
    int i=0;
    while(cadenas[i]!=NULL){
        free(cadenas[i]);
        i++;
    }
    free(cadenas);
}

// ...

This works mostly the same as the previous function, except you should use freeCadenas eventually, and I end the array with NULL instead of "" which is customary.

The code is a lot longer, but it's pretty typical of more sophisticated C code with less arbitrary limits. In fact real C code usually has more robust handling of errors and more generic functions for managing dynamic arrays. If you actually manage to make this "home-compiler", however, you will figure all this out for yourself.

Comments

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.