Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to divide a string into strings by whitespaces with pointers. I wrote the code below, but it does not work. Do you have any idea?
char sentence [] = "Thank you very much";
char * words [4]; //number of words
int i=0, charCounter=0, wordCounter=0;
while(sentence[i]){
char temp [5]; //maximum character count
while(sentence[i] != ' ' && sentence[i] != '\0'){
temp[charCounter] = sentence[i];
charCounter++;
i++;
}
temp[charCounter] = '\0';
words[wordCounter] = &temp[0];
wordCounter++;
charCounter = 0;
i++;
}
//there I want to write first word to check
int k;
for(k=0; k<12; k++)
printf("%c ", *(words[0]+k));
I think there isn't too much wrong aside from your output loops:
// write word by word
int k;
for(k=0; k < wordCounter; k++)
printf("%s ", words[k]);
// write first word byte by byte
k;
for(k=0; ((words[0])[k])!=0; k++)
printf("%c", (words[0])[k]);
Check this this code pad example based on your code above.
Only thing I changed was to allocate memory for words and copy the string using strcpy:
words[wordCounter] = malloc(sizeof(char) *(charCounter +1));
strcpy(words[wordCounter], &temp[0]);
Otherwise you assign always the same address (compare wrong example).
char temp[5] not need to save the start address of the word.
like as follows
char sentence [] = "Thank you very much";
char *words[sizeof(sentence) / 2] = {0};
int i=0, wordCounter=0;
while(sentence[i]){
while(sentence[i] == ' '){
++i;//skip space
}
if(sentence[i] == '\0')
break;
words[wordCounter++] = &sentence[i];//set top of word
while(sentence[i] != ' ' && sentence[i] != '\0'){
i++;//skip word
}
}
int k;
for(k=0; k<wordCounter; k++){
while(*words[k] != ' ' && *words[k] != '\0')
printf("%c", *words[k]++);
printf("\n");
}
You are adding a 6th char to an array of size 5!
Thats the error!
Also! You never reset the counter to 0, so as you keep going through words, you keep increasing the index added to temp as well
EDIT: I saw the temp[5]; above the while loop xD my Mistake!\
I believe your error lies in never declaring the temp[] array. In C, you must always provide an array with its size, as well.
Add this the line after you define sentence:
char temp[strlen(sentence)];
Also, a space and whitespace are two very different things.
Not all spaces are literally just a space!
However, to get a more accurate reading of any kind of space, using the function isspace, like so, is a much better practice:
while ((isspace(&sentence[i]) != 0) && (sentence[i] != '\0'))
hope this helps! :)
Related
I came across this strange loop behaviour in C. Here is the code:
char arr[SIZE];
fgets(arr, SIZE, stdin);
char brr[SIZE];
int i;
for(i=0; arr[i] != '\0'; i++){
if(arr[i] != ' ') brr[i] = (arr[i] + shift - 'a')%26 + 'a';
else brr[i] = ' ';
}
brr[i-1] = '\0';
The code is for Caesar cipher. It takes some text from the user and stores it in arr, then encodes it by shifting the characters, and this encoded version is put in brr. So, if user enters 'car' and shift is 2, brr is 'ect'.
The problem is in the last line. Normally, it should be brr[i] = '\0', but for some reason the loop will increase I once more after the condition is wrong. I have tried different combinations and it seems like the problem is somehow related to fgets.
Also, the problem is not specific to for loop, while behaves exactly the same.
Edit: Thanks for all the answers. I see now that I should have taken '\n' into account.
somehow related to fgets.
Always test the return values of input functions.
// fgets(arr, SIZE, stdin);
if (fgets(arr, SIZE, stdin)) {
// process arr[]
...
if user enters 'car' and shift is 2,
This is unlikely to only typed 'car' (3 characters). Certainly the user typed c a r Enter (4 characters) which filled arr[SIZE] with "car\n".
Rather than encode the 4 characters with if(arr[i] != ' '), test if arr[i] is a letter. Research isalpha().
Code could exit the for() loop early if '\n' is detected.
// for(i=0; arr[i] != '\0'; i++){
for(i=0; arr[i] != '\0' && arr[i] != '\n'; i++){
...
}
// brr[i-1] = '\0';
brr[i] = '\0';
Advanced
brr[i-1] = '\0'; is certainly a problem if i==0, possible if the first character read is a null character.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm new in C.
I've been asked to write a function that checks if the string has increasing/decreasing sequence of letters based on ASCII values + not includes white spaces(tabs,new lines etc.).
For example: demo is a very increasing string
beef is an increasing string
aa or zzz is an increasing string
tonic is a very decreasing string
spoon is a decreasing string
suddenly has no clear sequence.
So I wrote this code,it works but not so well..can you help me to improve it a little bit?
#include <stdio.h>
void f_sequence (char str[]);
int main()
{
char strl[101];
printf("your string is:\n");
scanf("%s\n", strl);
f_sequence(strl);
return 0;
}
void f_sequence(char str[])
{
int increase=0;
int decrease=0;
int match=0;
int i = 1;
if(!str[0])
printf("empty");
else if(!str[1])
printf("need more chars");
for(i=1; str[i]; i++)
{
if (str[i] == str[i-1])
match = 1;
if (str[i] > str[i-1])
increase = 1;
if (str[i] < str[i-1])
decrease = 1;
}
if((decrease==1) && (increase==0) && (match==0))
printf("we have a very descreasing sequence in here");
if((decrease==0) && (increase==1) && (match==0))
printf("we have a very increasing sequence in here");
if((decrease==1) && (increase==0) && (match==1))
printf("we have a descreasing sequence in here");
if((decrease==0) && (increase==1) && (match==1))
printf("we have an increasing sequence in here");
if((decrease==0) && (increase==0) && (match==1))
printf("we have an increasing sequence in here");
if((decrease==1) && (increase==1))
printf("not increasing and not decreasing");
puts("");
}
To ignore whitespaces, you can use isspace from <ctype.h> and skip in your calculations:
for(i = 1; str[i]; i++)
{
if (isspace((unsigned char)str[i])) continue;
...
}
But as is, you can't read input string with whitespaces as scanf with %s would stop reading at the first whitespace. You need fgets to read a line (so that you could read a string with whitespaces):
int main()
{
char strl[101];
printf("your string is:\n");
if (fgets(strl, sizeof strl, stdin)) {
char *p = strchr(strl, '\n');
if (p) *p = '\0'; // Remove newline if present
f_sequence(strl);
}
}
fgets would also read the newline character if there's space in the buffer which you may want to remove as shown (include <string.h> for strchr).
Use a function like below to remove whitespaces:
void removeSpaces(char *str)
{
// To keep track of non-space character count
int count = 0;
// Traverse the given string. If current character
// is not space, then place it at index 'count++'
for (int i = 0; str[i]; i++)
if (str[i] != ' ')
str[count++] = str[i]; // here count is
// incremented
str[count] = '\0';
}
And then add this function in the first line of f_sequence function. like this:
removeSpaces(str);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have to write a program that acts like a shell. I wrote the function that gets the input from the user. I also wrote the function that splits it into arguments. The first time I type something, it works well, but the second time, it prints different characters after the ones that I gave it. I don't have to print it in the program. I was just doing it to see if it works correctly. I read a bunch of stuff online, but I can't figure out my error. I suppose it is in makeArgs(), but I can't pinpoint it.
Also, when I give it an input, the readline function adds a \n at the end of the string. I suppose it is from the fact that I press the enter key. I managed to solve the issue, by manually replacing it, but I would like to know if it is normal.
Any help really be appreciated.
Thank You
Screenshot of Xterm after 2 inputs.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getText();
int makeArgs();
char *textEntre;
size_t nbCharacters;
char **arguments;
int main (void)
{
while (1){
getText();
int nbArguments = makeArgs();
for(int i =0; i<5; i++){
printf("%s \n",arguments[i]);
}
for(int i=0; i<nbArguments; i++){//free the char ptrs at the end
free(arguments[i]);
}
}
free(textEntre);
free(arguments);
return 0;
}
int getText(){
size_t buffersize = 0;
nbCharacters = getline(&textEntre, &buffersize, stdin);
textEntre[nbCharacters-1] =' '; // when I press enter it regiter the enter as \n so I replace it with a space
return 0;
}
int makeArgs(){
arguments = (char **)malloc(sizeof(char*)*20);
int i;
int j = 0;
int k = 0;
int nbElem = 20; //the number of ptrs that can be in arguments
for(i = 0; i<nbCharacters; i++){
if(i == 20){ //increases the memory allocated if there are more than 20 arguments
nbElem = nbElem *2;
arguments = (char **)realloc(arguments, sizeof(char*)*nbElem);
}
if(textEntre[i] == '"'){ //checks for ""
i++;
while(textEntre[i] != '"'){
i++;
}
}
if(textEntre[i] == ' ' && textEntre[i-1] == ' '){ // eliminates useless spaces
j++;
}
else if(textEntre[i] == ' '){ //save a single argument
char * chptr;
chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end
strncpy(chptr, &textEntre[j], i-j);
arguments[k] = chptr;
k++;
j = i +1;
}
}
return k;
}
chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end
You properly allocated memory for that terminating \0, but where do you actually add that "\0 at the end"?
strncpy(chptr, &textEntre[j], i-j);
strncpy does not necessarily zero-terminate the destination buffer. You have to do it yourself.
In fact, in this specific application strncpy is a rather inappropriate function: it does not give you anything over ordinary memcpy and might be less efficient. You could just do
memcpy(chptr, &textEntre[j], i - j);
with potentially better efficiency. And, again, don't forget to zero-terminate the destination buffer.
Or you can use sprintf for the same purpose as follows
sprintf(chptr, "%.*s", i - j, &textEntre[j]);
which will produce a properly zero-terminated string in the destination. (Albeit you won't see sprintf used that way very often.)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am trying to read in the words of a sentence entered by the user one by one, by putting each word into an array, however I could not come up with a good solution.
I have tried:
printf("Enter your sentence: ");
while(scanf("%s", word) != EOF)
{
wordArray[i] = word;
i ++;
}
where wordArray is a string array, i is an integer and word is a string.
I would have liked this to read each word of a sentence and put it in the array.
For example, if I entered "I am Mark", I would have liked this snippet of code to put:
"I" in wordArray[0]
"am" in wordArray[1]
"Mark" in wordArray[2]
However, this method doesn't work, so could anyone please give me a method to read each word of the sentence one by one?
You cannot copy strings like this in C. To copy a string from one char array to another, you must use strcpy.
You must pay attention though, that the char arrays are large enough for the words entered, therefore the declaration might look
char word[256];
char wordArray[10][256];
And to prevent buffer overruns, you should check for the index i as well as give a maximum field length to scanf
while(i < 10 && scanf("%255s", word) != EOF)
{
strcpy(wordArray[i], word);
i++;
}
You cann't use assignment operator to assign a string to another string as like others data type such int, float. You should use strcpy() library function which needs
string.h header file. You code should be:
printf("Enter your sentence: ");
while(scanf("%s", word) != EOF)
{
strcpy(wordArray[i],word);
i ++;
}
There are few ways to make array of strings in C:
const char *arr[10];
arr[0] = "hello"
arr[1] = "world"
Or, making a 2D array of chars
char arr[10][100];
strcpy(arr[0], "hello");
strcpy(arr[1], "world");
And it's better to read word by word from input stream, with
char temp[100];
scanf("%s", temp)
Declare wordArray as an array of n, say, pointers to char, and allocate memory for each of them. Say, 20 bytes for each:
char word[20];
int n = 10;
char *wordArray[n];
for(int i = 0; i < n; i++)
wordArray[i] = malloc(20);
and then your code will work.
printf("Enter your sentence: ");
int i = 0;
while(scanf("%s", word) != EOF && i < n)
{
strcpy(wordArray[i], word);
}
Do not forget to free wordArray elements.
#include<stdio.h>
#include<string.h>
int main()
{
char ch,word[20][20];
static int i,j;
printf("Enter the sentence: ");
ch=getchar();
while( ch != '\n' )
{
if (ch == ' ' )
{
word[i][j] = '\0';
i++;
j=0;
}
else
word[i][j++] = ch;
ch = getchar();
}
for ( j=0;j<i;j++)
{
puts(word[j]);
}
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
The task is to be sure that phrases are can be readed vise versa or not (without spaces ' ').
So I got the point and made some code. But when I made
printf("%s", str_1)
I found a lot of same russian letters.
For example my inputs are: '123' '321', but displayed rubbish
My str_1[i] is going to be like 123321 and then checked first and last and so on members.
After that I added in if condition if(str[i] != 'М') and now everything nice.
Please tell me what I did wrong and what is going on with "M".
I hope my question is clear.
#include "stdio.h"
#include "locale.h"
int main(){
char str[100];
char str_1[100];
int i, j, k, l;
j = 0;
l = 0;
fgets(str, 100, stdin); //we got array
//how many chars before '\0'
for(i = 0; i < 100; i++)
{
if(str[i] != ' ' && str[i] != '\n' && str[i] != 'М')
{
str_1[j] = str[i]; //made new array without spaces between words or whatever
j++;
}
}
j--;
for(k = 0; k < j; k++)
{
if(str_1[k] == str_1[j - 1 - k])
{
l++;
}
}
if( l == k)
{
printf(";) YES! good job!\n");
}
else
{
printf(";) NOT! I'm sorry!\n");
}
return 0;
}
As it seems, you skip over the end of the string, as you never check where it ends.
At least, this is my suspicion; I am not sure if it is the right reason.
You should check for str[i] == '\0' as well and then break the whole loop.
As I see, you even made this consideration in
//how many chars before '\0'
but didn't include it in code.
A
for(i = 0; i < 100 && str[i] != '\0'; i++)
should do the trick if you omit the j-- afterwards.