How to split string input? - c

This is part of my main function, the problem is: if my input for translation is given more than one word the program doesn't work properly, any idea about how can I fix that?
int main() {
struct node *temp;
char str[1000];
char word[MAXP];
char translation[MAXT];
char option[15];
while (1) {
str[0] = '\0';
word[0] = '\0';
translation[0] = '\0';
scanf("%[^\n]%*c", str);
sscanf(str, "%s %s %s", option, word, translation);
}
...

You can use fgets to read each input. Then sscanf to scan for the first two sub-strings. Using the %n specifier, the number of characters scanned can be captured to allow you to use strcpy from that index.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char end = '\0';
char str[1000];
char word[1000];
char translation[1000];
char option[15];
int used = 0;
int scanned = 0;
while(1){
str[0]='\0';
word[0]='\0';
translation[0]='\0';
fgets ( str, sizeof ( str), stdin);
str[strcspn ( str, "\n")] = '\0';//remove newline
scanned = sscanf(str, "%14s%999s%c%n", option, word, &end, &used);
if ( scanned >= 1) {//one sub string scanned
printf ( "%s\n", option);
}
if ( scanned >= 2) {//two sub strings scanned
printf ( "%s\n", word);
}
if ( scanned == 3) {//two sub strins and a character scanned
strcpy ( translation, &str[used]);
printf ( "%s\n", translation);
}
}
return 0;
}

Related

How to exit code if nothing is entered? Code example: Check if string is a palindrome or not? (in C Programming Language)

QUESTION: How to exit code if nothing is entered into STDIN (console)?
For example:
*Input
"NULL - NOTHING - ZERO" :)
Expected Output
(Close program quit loop)*
Input:
Hello
Output:
Hello is not a palindrome
Input:
otto
Output:
otto is a palindrome
Code Explanation:
A palindrome is a string phrase that reads the same backwards as well as forwards. Examples of palindromes are “ABCDCBA”, “otto”, “i am ma i”, “C”. Write a program that reads in a line of text, and prints out whether or not that line of text is a palindrome.
#include <stdio.h>
#include <string.h>
#define MAXLEN 100
void reverseString(char *str, char *reversedStr)
{
int i;
for (i=strlen(str)-1; i>=0; i--)
{
*reversedStr++ = *(str+i);
}
*reversedStr = '\0';
}
int main(int argc, char **argv) {
char str[MAXLEN];
char reversedStr[MAXLEN];
while (fgets(str, sizeof(str)-1, stdin) != NULL)
{
str[strlen(str)-1] = '\0'; // the last character is the newline. Replace with null
reverseString(str, reversedStr);
if (strcmp(str, reversedStr) == 0)
printf("%s is a palindrome\n", str);
else {
printf("%s is not a palindrome\n", str);
}
}
return 0;
}
Code Snippet:
https://onlinegdb.com/ByGKe8LnE
Your code works. Just press ctrl-d right after enter (signals end of input) to exit.
Couple of other things:
fgets() doesn't need size minus 1. per the manual: "fgets() reads in at most one less than size characters..."
there is really no need to copy/reverse the entire string and compare, half will suffice, OR you could simply compare beginning with end until center, without copying.
strlen() "walks" the string - you can reuse the result of it instead of calling again.
.
#include <stdio.h>
#include <string.h>
#define MAXLEN 100
int isPalindrome(char *str, size_t len) {
char *end = str + len - 1;
while (end > str)
if (*end-- != *str++) return 0;
return 1;
}
int main(int argc, char **argv) {
char str[MAXLEN];
while (fgets(str, sizeof(str), stdin) != NULL) {
size_t len = strlen(str) - 1;
str[len] = 0; // the last character is the newline. Replace with null char
printf("%s is %sa palindrome\n", str, isPalindrome(str, len) ? "" : "not ");
}
return 0;
}

split string value in arrays

I have to split a string-input value where-ever there is a blankspace and output the result.
eg: input:
I am a noob at C
output:
>>I
>>am
>>a
>>noob
>>at
>>C
Code:
void splitText(){
char str[100];
char sep[] = " \r\n";
char *res; //if i remove this
fgets(str,sizeof str,stdin);
if (fgets(str, sizeof str, stdin) == NULL) {
printf("error");
}
char *p = strchr(str, '\n');
if (p) *p = 0;
res = strtok(str, sep); //and this
printf("%s\n",res); //and change this to str
}
Working code for anyone encountering the same problem:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void splitText() {
char str[100];
char sep[] = " \n";
char *res;
fgets(str,sizeof str, stdin);
if ( fgets(str, sizeof str, stdin) == NULL ) {
printf("Error");
break;
}
res = strtok(str, sep);
while(res != NULL){
printf("Splitted String: \"%s\"\n",res);
res = strtok(NULL,sep);
}
}
Thanks to everyone who contributed in helping me with this issue!
The problem with
char str[100] = scanf("%s",str);
is that you are assigning an int to a char array.
scanf() returns the number of items successfully scanned. The actual reading of chars into the array is done by scanf() itself. So you just need to call scanf() separately.
if (scanf("%s",str) != 1) { /* error */}
But scanf() is not the right tool here since you want to read a whole line. scanf() would stop at the first whitespace (after reading non-whitespace chars).
So when you type "I am a noob at C", scanf() will only read the I and ignore the rest.
What you want is to use the fgets() function to read a line:
char str[100];
if (fgets(str, sizeof str, stdin) == NULL) {
/* error */
}
/* rest of the code */
fgets() would read the newline as well if there's space in the buffer. If this is undesirable, then you can remove it:
char *p = strchr(str, '\n');
if (p) *p = 0; //remove the trailing newline.
Note: strtok() is not a thread safe function. POSIX provides strtok_r() as a thread-safe alternative. This is something to be aware of even if it doesn't matter in this specific case.
Here's a self contained example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char str[100];
char sep[] = " \n";
char *res;
if ( fgets(str, sizeof str, stdin) == NULL ) {
exit(1);
}
res = strtok(str, sep);
while(res != NULL){
printf("Splitted String: \"%s\"\n",res);
res = strtok(NULL,sep);
}
return 0;
}
That is not how scanf() works.
Change the code to
char str[100];
scanf("%s",str);
A little note about scanf()
You should check for return values, like here for scanf().
if (scanf("%s", str) != 1)
{
printf("scanf failed");
exit(0);
}
You should also mention the number of chars to be read by scanf() to avoid buffer overflow.
scanf("%99s", str)
For a char str[100] of size 100, one should give 99 to keep place for the null character \0.

read 1/2/5 string inputs in c

i need to read input from the standart input line by line
but each line will contain 1 or 2 or 5 strings like :
bofob fbo
blabla bibi bobo fbo fbooo
bobobo bobo
bobof
how can i do this?
my idea is really not looking profassional and not working
char a[50],b[50],c[50],d[50],f[50];
int numOfStrings=0;
scanf(" %s",a); char a[50],b[50],c[50],d[50],f[50];
int numOfStrings=0;
scanf(" %s",a);
if (scanf (" %s",b)){
numOfStrings=2;
if (scanf (" %s %d %d",c,d,f)
numOfStrings=5;
}
if (scanf (" %s",b)){
numOfStrings=2;
if (scanf (" %s %d %d",c,d,f)
numOfStrings=5;
}
but its not working because it goes and read inputs from the next line
is there a way to read a whole line (i know its max 250 chars) and then know how many words are in there?
edit:
i will add a count words function
but what is the nicest wat ro read a line untilll the end line or eof??
int words(const char *sentence)
{
int count,i,len;
char lastC;
len=strlen(sentence);
if(len > 0)
{
lastC = sentence[0];
}
for(i=0; i<=len; i++)
{
if(sentence[i]==' ' && lastC != ' ')
{
count++;
}
lastC = int words(const char *sentence)
}
return count;
}
You need to use fgets() to take the input line-by-line. check the man page here. It will also liberate you from handling the limitation of [1/2/5/.....] numbers of space-seperated strings. Provided sufficient storage, you can read 1 to any number of "string"s.
Note: You might need to take care of the trailing newline \n [caused by ENTER] yourself. Causes trouble most of the times.
You could scan one line until the '\n' with %[^\n], then split the line into words with strtok():
#include <string.h>
#include <stdio.h>
const char s[2] = " ";
const int MAX_LINE_SIZE = 128;
FILE *fp;
char *word, *str;
int word_counter;
/* Open the file here */
while (fgets(str, MAX_LINE_SIZE, fp) != NULL)
{
word_counter = 0
/* get the first word */
word = strtok(str, s);
/* walk through other words */
while (word != NULL)
{
printf(" %s\n", word);
word_counter++;
word = strtok(NULL, s);
}
printf("This string contains %d words\n",word_counter);
}
/* END of FILE */
You can use fgets to read a file and strchr to count the number of spaces:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[250];
char *p;
FILE *f;
int i;
f = fopen("demo.txt", "r");
while ((p = fgets(s, sizeof s, f))) {
i = 0;
while ((p = strchr(p, ' '))) {
p++;
i++;
}
printf("%d spaces\n", i);
}
fclose(f);
return 0;
}

Function to delete all occurrences of a word in a sentence in C

I have this code which will remove the first occurrence of the word from the sentence:
#include "stdio.h"
#include "string.h"
int delete(char *source, char *word);
void main(void) {
char sentence[500];
char word[30];
printf("Please enter a sentence. Max 499 chars. \n");
fgets(sentence, 500, stdin);
printf("Please enter a word to be deleted from sentence. Max 29 chars. \n");
scanf("%s", word);
delete(sentence, word);
printf("%s", sentence);
}
int delete(char *source, char *word) {
char *p;
char temp[500], temp2[500];
if(!(p = strstr(source, word))) {
printf("Word was not found in the sentence.\n");
return 0;
}
strcpy(temp, source);
temp[p - source] = '\0';
strcpy(temp2, p + strlen(word));
strcat(temp, temp2);
strcpy(source, temp);
return 1;
}
How would I modify it to delete all occurrences of the word in the given sentence? Can i still use the strstr function in this case?
Thanks for the help!
Open to completely different ways of doing this too.
P.S. This might sound like a homework question, but it's actually a past midterm question which I'd like to resolve to prepare for my midterm!
As a side question, if I use fgets(word, 30, stdin) instead of scanf("%s", word), it no longer works and tells me that the word was not found in the sentence. Why?
Try the following
#include <stdio.h>
#include <string.h>
size_t delete( char *source, const char *word )
{
size_t n = strlen( word );
size_t count = 0;
if ( n != 0 )
{
char *p = source;
while ( ( p = strstr( p, word ) ) != NULL )
{
char *t = p;
char *s = p + n;
while ( ( *t++ = *s++ ) );
++count;
}
}
return count;
}
int main( void )
{
char s[] = "abxabyababz";
printf( "%zu\n", delete( s, "ab" ) );
puts( s );
return 0;
}
The output is
4
xyz
As for the question about fgets then it includes the new line character in the string. You have to remove it from the string.
How would I modify it to delete all occurrences of the word in the given sentence?
There are many ways, as you have suggested, and since you are Open to completely different ways of doing this too...
Here is a different idea:
A sentence uses white space to separate words. You can use that to help solve the problem. Consider implementing these steps using fgets(), strtok() and strcat() to break apart the string, and reassemble it without the string to remove.
0) create line buffer sufficient length to read lines from file
(or pass in line buffer as an argument)
1) use while(fgets(...) to get new line from file
2) create char *buf={0};
3) create char *new_str; (calloc() memory to new_str >= length of line buffer)
4) loop on buf = strtok();, using " \t\n" as the delimiter
Inside loop:
a. if (strcmp(buf, str_to_remove) != 0) //approve next token for concatenation
{ strcat(new_str, buf); strcat(new_str, " ");}//if not str_to_remove,
//concatenate token, and a space
5) free allocated memory
new_str now contains sentence without occurrences of str_to_remove.
Here is a demo using this set of steps (pretty much)
int delete(char *str, char *str_to_remove)
{
char *buf;
char *new_str;
new_str = calloc(strlen(str)+1, sizeof(char));
buf = strtok(str, " \t\n");
while(buf)
{
if(strcmp(buf, str_to_remove) != 0)
{
strcat(new_str, buf);
strcat(new_str, " ");
}
buf = strtok(NULL, " \t\n");
}
printf("%s\n", new_str);
free(new_str);
getchar();
return 0;
}
int main(void)
{
delete("this sentence had a withh bad withh word", "withh");
return 0;
}

Remove leading zeros error

I am trying to remove the leading zeros of the number user enters so 000002 will turn into 2
However, I am getting an error saying Segmentation fault (core dumped)
#include <stdio.h>
#include <string.h>
int main()
{
char *str;
scanf("%c", *str);
int n;
if( ( n = strspn(str, "0" ) ) != 0 && str[n] != '\0' ) {
printf("String without leading zeros is %s \n", &str[n]);
} else {
printf("No leading zeros in %c \n", str);
}
return 0;
}
Change %c to %s and *str to str.
You don't need to use the * when scanning.
Besides the errors pointed out in the previous answers, scanf("%d") will take care of removing leading zeroes for you. Do the test:
#include <stdio.h>
int main()
{
int a;
scanf("%d", &a);
printf("%d\n",a);
return 0;
}
And if you absolutely need a string, just convert with sprintf:
#include <stdio.h>
int main()
{
char str[256];
int a;
scanf("%d", a);
sprintf(str, "%d", a);
puts(str);
return 0;
}
remove * from this:
scanf("%c", *str);
and change %c to %s because you are scanning a string not character
As #user3291093 has said, you need to change %c to %s since you are reading a string/char array and not a single character.
Also you need to malloc an area to store the array. For example:
char *str = NULL;
str = malloc(100*sizeof(char));
scanf("%s", str);
The compiler should have warned about this problem. Insure warnings are enabled.
char *str;
scanf("%c", *str); // "%c" does not match `*str` for scanf()
Suspect OP wanted something like
char str[100];
if (scanf("%99s", str) == 1) Continue_Along_the_Happy_Path();
An alternative fgets() solution.
char str[100];
fgets(str, sizeof str, stdin);
char *p = buffer;
while (*p == '0') p++;
if (p != buffer) {
printf("String without leading zeros is %s", p);
} else {
printf("No leading zeros in %s", str);
}

Resources