Alright, here's what I'm working on now. It's supposed to go through an inputted list of words, pick out actual words and create a numbered list of them, then, where it finds a number in the list, go back in the list from that number, replace it with a word, augment the list accordingly and continue.

Anyways, here's what I have:

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

int main ()
{
    char line[100];
    char word[100];
    char tword[20];
    
    int k = 0, index = 0, nwords = 0, j;    

    gets(line);
    
    while(line[0] != '0')
    {
        if(isalpha(line[k]))     
        {
            j = 0;
            while (isalpha(line[k]))
            {
                tword[j] = line[k];
                j++;
                k++;
            }
            tword[j] = '\0';
            strcpy(word[nwords], tword);
            nwords++;
        }
        else if(isdigit(line[k]))
        {
            index = atoi(line[k]);
            k++;
            if(isdigit(line[k]))
            {
                index = index * 10  + atoi(line[k]);
                k++;
            }
            printf("%s", word[nwords - index]);
            strcpy(tword, word[nwords-index]);
            for(j  = index + 1; j < nwords; j++)
            {
                strcpy(word[j - 1], word[j]);
            }
            strcpy(word[nwords - 1], tword);
        }
        else
        {
            printf("%c", line[k]);
            k++;
        }
    gets(line);    
    }
    return 0;
}

The problem is that I get segmentation faults when executing. Anybody see what I'm missing?

Recommended Answers

All 6 Replies

Several problems in your code.

  1. gets has no bounds-checking when it gets input, instead you should use fgets .
  2. This code: strcpy(word[nwords], tword);
    This is copying an entire string into 1 character of the string. Use 2d array of chars if you want to have an array of strings.
  3. strtol might be a better function to use instead of atoi if you wish to perform error-checking number conversion.

Several problems in your code.

  • gets has no bounds-checking when it gets input, instead you should use fgets .
  • This code:
    strcpy(word[nwords], tword);

    This is copying an entire string into 1 character of the string. Use 2d array of chars if you want to have an array of strings.

I implimented both of those, but to no avail. Here's the new version:

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

int main ()
{
    char line[100];
    char word[20][100];
    char tword[20];
    
    char *linePtr;
    
    int k = 0, index = 0, nwords = 0, j;    

    fgets(line, 100, stdin);
    
    while(line[0] != '0')
    {
        if(isalpha(line[k]))    
        {
            j = 0;
            while (isalpha(line[k]))
            {
                tword[j] = line[k];
                j++;
                k++;
            }
            tword[j] = '\0';
            strcpy(word[nwords], tword);
            nwords++;
        }
        else if(isdigit(line[k]))
        {
            *linePtr = line[k];
            index = atoi(line[k]);
            k++;
            if(isdigit(line[k]))
            {
                index = index * 10  + atoi(line[k]);
                k++;
            }
            printf("%s", word[nwords - index]);
            strcpy(tword, word[nwords-index]);
            for(j  = index + 1; j < nwords; j++)
            {
                strcpy(word[j - 1], word[j]);
            }
            strcpy(word[nwords - 1], tword);
        }
        else
        {
            printf("%c", line[k]);
            k++;
        }    
    }
}

I'm surprised your code even compiles (it doesn't actually, I just tried compiling it with gcc and it failed with several syntax errors).

Why are you looping until the first character of line is 0? My only guess is that the list of words is terminated with a 0, but then you'd have to use a variable to keep track of the iterations, and then use this as your array subscript.

And why do you keep a separate variable tword for copying the strings? Save yourself a strcpy call and just copy it directly into the string array.

Your number extraction is totally screwed. You only feed a single char to atoi . Giving atoi a single char not only results in a compiler error, but there could in fact be more than 1 digit in the number. Try creating a loop that goes until it encounters a non-numeric character, and then feed the string obtained back to atoi .

And finally, why is the printf() statement in the word extraction loop? Create a separate loop after the extractions are all said and done, and you might actually get some console output!

Hope this is not what you posted it for:
test.cpp(43) : warning C4700: local variable 'linePtr' used without having been initialized

Line 43 in my test.cpp is "*linePtr = line[k];"

I dont see the login behind this code. You have been all around. Why do u want to loop around with the string just to copy when u have a routines to do that.

What is that u wanted, explain it properly.

ssharish2005

Here's how I interperted your problem:
Given a list of Words and Numbers:
--Make a numbered list of the words.
--Replace numbers with words from the list.

Instead of a console program, I wrote a program that takes a filename at command line. I expect one word or number per line, and output to the second filename, or the first filename +".new" if only one argument is given.

Other than the file aspect, the algorithm should be pretty straight forward. I used an array of arrays for the strings, and kept how many word are in it with a variable. Max size is hard coded at 4095 words. I have one function to check the array for a word, it returns -1 if it is not found.

This compiles and runs without errors or warnings under Visual C++ 6, should be fine under other compilers.

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

int find_word(const char ** array, const int size, const char * item)
{

  int i = 0;
  
  while (i < size)
  {
    if (strcmp(array[i], item) == 0)
      return i;
    else
      i++;
  }

  return -1;

}

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

  char filename[65536], outputfilename[65536];
  FILE * file;
  FILE * outputfile;
  char buffer[256];
  char * array[4096];
  int size = 0;
  int pos;

  if (argc == 1)
  {
    printf("Not enought parameters!\n");
    return 1;
  }

  if (argc > 1)
  {
    strcpy(filename, argv[1]);
  }

  if (argc > 2)
  {
    strcpy(outputfilename, argv[2]);
  }
  else
  {
    strcpy(outputfilename, filename);
    strcat(outputfilename, ".new");
  }

  file = fopen(filename, "r");
  outputfile = fopen(outputfilename, "w");

  if ((file == NULL) || (outputfile == NULL))
  {
    printf("Error opening file\n");
    return 2;
  }

  while(!feof(file))
  {
    if (fgets(buffer, 256, file) == NULL) break;

    pos = strlen(buffer) - 1;
    if (buffer[pos] == '\n') buffer[pos] = 0; // remove trailing LFCR's

    if (isalpha(buffer[0])) // word
    {
      pos = find_word(array, size, buffer);
      if (pos == -1) // word is not in the array, must add it.
      {
        if (size == 4095) exit(3); // size check for array

        array[size] = (char *) malloc(256 * sizeof(char));
        if (array[size] == NULL) exit(3); // check malloc()!!
        strcpy(array[size], buffer);
        printf("%s added at %i\n", buffer, size);
        size++;
      }
      // nothing else, do nothing on duplicate words
    } // end of if -- isalpha
    else // word is already in the array!
    {
      pos = atoi(buffer);
      if (pos >= size)
      {
        printf("Error! %d not in the array!!\n", pos);
      }
      else
      {
         strcpy(buffer, array[pos]);
         printf("Replacing %d with %s\n", pos, buffer);
      }
    }

    fputs(buffer, outputfile);
    fprintf(outputfile,"\n");

  }

  fclose(file);
  fclose(outputfile);

}

Hope that answers your problem. I found it easier to assume what you were trying to do it, and show how I would do it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.