How to read part of string into smaller string - c

I am reading a line from a .txt file. My goal right now is to read the first word of the line. I have the line stored in a string declared char *text. Then I have a double pointer to that string char** charReader which will read the letters of the string. I am trying to read the characters in one by one into a new string char* word, and stop when I hit a space, however I have gotten a segmentation fault in doing so.
Here is my code to perform that function:
while(isalpha(**charReader) != 0){
word[i] = **charReader;
charReader++;
i++;
}
My goal is to output the value of word. But my code seems to be giving me a segmentation fault.

The variable charReader is a pointer to a pointer to char (you can think of it as being an array of strings or a matrix of chars), while the variable word is a string (an array of chars). Therefore, when you do:
word[i] = **charReader;
you are trying to make an assignment involving incompatible types (treating a double pointer to char as if it was a char). That's why you are getting an error.
To copy the first word of a string into another string, you can try something like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char text[] = "This is a string with multiple words.";
int i = 0;
while(i++ < strlen(text) && text[i] != ' '); //seek for the index of the first space character in "text"
char *word = malloc((i + 1) * sizeof(char));
strncpy(word, text, i); //"word" now stores the first word of "text"
printf("%s\n", word);
free(word);
return 0;
}

Related

Concatenating two strings in C and recieve a signal SIGABRT error in Xcode

I am trying to concatenate two strings in C and receive a "Thread 1: signal SIGABRT" error.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
int main() {
char name[50];
ifile = fopen("stats.list", "r");
for(;;) {
fscanf(ifile, "%s%f%f", name, &sky, &stddev);
if (feof(ifile))
break;
char ext[5] = ".par";
dataparsFile = strcat(name, ext);
dataparsFile = fopen(dataparsFile, "w");
fprintf(dataparsFile, "%s\n",
"stuff gets read in to file named after new string";
fprintf(ofile, "phot ");
fprintf(ofile, "%s%s%s%s%s%s \n",
", datapars=", dataparsFile);
}
fclose(ifile);
fclose(ofile);
The goal of the code is to take an image name that is read in and add on the .par extension. Then, I want to open a file with that name of image+.par and write into it. Since I will have a couple hundred such files, I need to loop through them with the name changing each time.
The problem is name is not initialized. You see, in c strings use a convention, they are any sequence of ASCII (probably some other printable characters, but in principle just ASCII) that must be followed by a '\0' byte that marks the end of the string.
Your name array doesn't have this '\0' so strcat() tries to find it but it fails and perhaps it reads beyond the end of the array, although anyway reading uninitialized data is undefined behavior.
The way strcat(dst, src) works is pretty much like this
char *
strcat(char *const dst, char *src)
{
// Make a pointer to keep dst's address
// unchanged and return it
char *ptr = dst;
// Compute search for the end of the destination
// string to start copying there
while (*ptr != '\0')
ptr++;
// Copy all the characters from `src' until the '\0'
// occurs
while (*src != '\0')
*(ptr++) = *(src++);
*ptr = '\0';
return dst;
}
As you see, this is very inefficient if you call strcat() many times, and it will certainly not work if you pass either of the parameters before initializing it.
In fact, it's terribly unsafe because there is no bound checking, the caller has to make sure that the destination array is large enough to hold both strings.

How to strcat 1 character from a 2d array to a 1d array

Essentially I'm trying to strcat a letter from a 2d array onto a 1d array. I've got this user inputted grid of letters and from these letters I'm combining them letter by letter into a 1d array and checking it against a dictionary to see if its a valid word.
I've been trying something like
strcat(wordTester, board[i][j]);
but I keep getting runtime errors. Any help would be appreciated.
strcat() is for connecting null-terminated string, so passing a character to it will lead to crush because the character will likely converted to an invalid pointer.
Try using this functon:
#include <string.h>
char* charcat(char *target, char c) {
size_t len;
if (target != NULL) {
len = strlen(target);
target[len] = c;
target[len + 1] = '\0';
}
return target;
}
Usage (assuming char wordTester[MAX]; char board[M][N]; where MAX, M and N are properly defined):
charcat(wordTester, board[i][j]);

Crash when comparing strings in C

Ok so i am trying to write a function that checks whether or not a letter of a word exists within an array of strings(It does that for every letter in the word). After tinkering with it for a while, i figured that it crashed when it tried to use the strcmp(). I don't know what i am doing wrong since i just started learning C so any help would be appreciated. Here is the function:
char SingleChar(char *lex, int wordnum,char *word){
int i,j,k;
for(i=0;i<strlen(word);i++){
for(j=0;j<wordnum;j++){
for(k=0;k<strlen(lex[j]);k++){
if(strcmp(word[i],lex[k])){
return word[i];
}
}
}
}
return 0;
}
You have a misunderstanding about what char * means. It is a pointer to character. In C string are just a pointer to a character, flowed by other characters and a null terminator. What this means in your case, is that lex is a single string, not a list of strings.
ie
char *a = "imastring"; denotes that a is the address of a sequential piece of memory containing the characters [i][m][a][s][t][r][i][n][g][\0]. In C the null terminator is used to denote the end of a string.
What this means is that when you are calling strlen(lex[j]) you are just referencing a single character in lex and then reading to the end of the string, so your result will just decrease monotonically.
You probably want to do is use a double pointer. char ** list will point to an address, which points to an address referencing a block of sequential characters.
char ** list = (char **)malloc(sizeof(char *) * 5); would allocate you 5 sequential memory address which could then point to strings themselves. And you can assign them values as follows.
list[0] = a
I hope this helps.
Don't really see an array of strings... Your C file should look roughly like this:
#include <stdio.h>
char SingleChar(char *lex, int wordnum, char *word){"your function in here"};
int main(){
// Declare your variables here
// Call your function here SingleChar(params)
return 0;
}
To compare characters:
if(word[i]==lex[k]){
return word[i];
break;
}
Not quite sure what you are trying to do with your function other than that. You need to be more specific, I don't see your array of strings input.
In C there is no true string type. A string in C is just an array of characters.
An array of strings would be an array of pointers to an array of characters in memory.
If you wanted to check for a letter within an array of "strings".
You would want a pointer that moves through each letter of the array and compares each character.
The strcmp() function will return true (1) or false (0), depending on whether the strings are equal or not.
So what you'd want I think is for your program to compare the characters of your word with every other word in the array of strings.
This program goes through the entire word then tells you if the letter exists.
For each letter of whatever word you enter.
--
#include <stdio.h>
#include <string.h>
/*
Function to check for a letter of a word
in an array of strings */
void singleChar(char *word,int arrlength, char *strings[])
{
int length = 0;
length = strlen(word); /* Calculates the length of the string */
for(int y = 0; y < arrlength ; y++) /*Increments to the next word in the array */
{
for(int i=0; i <= length ; i++) /*increments to the next letter of the word you want to check */
{
for(int x=0; x < strlen(strings[y]) ; x++) /*Increments x based on the length of the string */
{
char *p = strings[y];
if(word[i] == p[x]) /*Compares the the first letter of both strings */
{
printf("The letter %c exists.\n", word[i]);
}
}
}
}
}
int main ( void )
{
/*Example */
char *p = "Hello";
char *a[2];
a[0]="Hello";
singleChar(p, 1,a);
}

C Reading words from text file

I'm writing a simple function that takes as input 3 already opened FILES's, then scans through each character in the file, filling up a char array until a ' ' whitespace is reached or a newline is found. However, my method of filling an array keeps giving me a Segmentation fault and I'm not really sure why. For now I am just attempting to print to console the words that were filled in the word[] array, then clearing it with memset for the next word.
hash_table_t training(FILE *D1, FILE *D2, FILE *D3, int size)
{
char *word[200];
char c;
int i = 0;
while ((c = fgetc(D1)) != EOF)
{
while (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')))
{
//add to char array
*word[i++] = c;
}
if(c == ' ' || c=='\n')
{
//hash word (print chars for now)
for (i=0; *word[i] != ' '; i++)
{
printf("%c", *word[i]);
}
}
memset (word, ' ', 20);
}
fclose(D1);
fclose(D2);
fclose(D3);
}
Your wordarray is a array of pointer, not a array of character.
You should change
char* word[200];
to
char word[200];
and
*word[i];
to
word[i];
You declared word as an array of character pointers, assign them characters, and try to dereference those values.
The variable "word" as you have declared it is not a char array/cstring, but it is a pointer to a string with a size of 200; this would work but you have not initialized the string with "malloc" hence the "Segmentation Fault" error as you are trying to change a part of memory not allocated to your program.
Edit: Also, as a tip, always initialize pointers as soon as creation; because they are pointing to random parts of memory upon creation, the code may not always give you a "Segmentation Fault" error, because it may point to a part of memory that IS allocated to your program.
Worst case, you will have a really hard-to-track bug.

Printing an array of characters

I have an array of characters declared as:
char *array[size];
When I perform a
printf("%s", array);
it gives me some garbage characters, why it is so?
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
This url indicates printf takes in the format of: `int printf ( const char * format, ... );
#include <stdio.h>
#include <string.h>
#define size 20
#define buff 100
char line[buff];
int main ()
{
char *array[100];
char *sep = " \t\n";
fgets(line, buff, stdin);
int i;
array[0] = strtok(line, sep);
for (i = 1; i < size; i++) {
array[i] = strtok(NULL, sep);
if (array[i] == NULL)
break;
}
return 0;
}
You declare an array of characters like so:
char foo[size];
You seem to have it mixed up with char *, which is a pointer to a character. You could say
char *bar = foo;
which would make bar point to the contents of foo. (Or, actually, to the first character of foo.)
To then print the contents of the array, you can do one of the following:
// either print directly from foo:
printf("%s", foo);
// or print through bar:
printf("%s", bar);
Note, however, that C performs no initialization of the contents of variables, so unless you specifically set the contents to something, you'll get garbage. In addition, if that garbage doesn't happen to contain a \0; that is, a char with value 0, it will keep on outputting past the end of the array.
Your array is not initialized, and also you have an array of pointers, instead of an array of char's. It should be char* array = (char*)malloc(sizeof(char)*size);, if you want an array of char's. Now you have a pointer to the first element of the array.
Why are we making such a simple thing sound so difficult?
char array[SIZE];
... /* initialize array */
puts(array); /* prints the string/char array and a new line */
/* OR */
printf("%s", array); /* prints the string as is, without a new line */
The char in array after the end of what you want to be your string (ie. if you want your string to read "Hello" that would be the next char after the 'o') must be the terminating NUL character '\0'. If you use a C function to read input that would automatically be appended to the end of your buffer. You would only need to worry about doing it manually if you were individually writing characters to your buffer or something for some reason.
EDIT: As with pmg's comment, the '\0' goes wherever you want the string to end, so if you wanted to shorten your string you could just move it up closer to the front, or to have an empty string you just have array[0] = '\0';. Doing so can also be used to tokenise smaller strings inside a single buffer, just as strtok does. ie. "Part1\0Part2\0Part3\0". But I think this is getting away from the scope of the question.
ie. you wanted to store the first 3 chars of the alphabet as a string (don't know why anyone would do it this way but it's just an example):
char array[4];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = '\0';
printf("%s\n", array);
If you have something like char array[] = "Hello"; the '\0' is automatically added for you.
char *array[size];
array is not a char * with that, it's more like a char ** (pointer to an array of chars, with is similar to pointer to pointer to char).
If all you need is a C string, either:
char array[size];
and make sure you 0-terminate it properly, or
char *array;
and make sure you properly allocate and free storage for it (and 0-terminate it too).

Resources