I'm learning string in c, and i'm working on my homework which ask me to write a program to replace part of string under certain circumstances. Here is my source code(undone):
#include <stdio.h>
#include <string.h>
int main()
{
char str1[128], str2[128], str3[128];
for (int i = 0; i < 128; i++) //initialize str
{
str1[i] = 0;
str2[i] = 0;
str3[i] = 0;
}
printf("Input the first string:"); //inputs
fgets(str1, 128, stdin);
printf("Input the second string:");
fgets(str2, 128, stdin);
printf("Input the third string:");
fgets(str3, 128, stdin);
if (strncmp(str1, str2, strlen(str2) - 1) == 0) //if the first n charters match (n=length of str2)
{
printf("%s", str3); //print str3
int RemainingChar = 0;
RemainingChar = strlen(str1) - strlen(str2);
for (int i = 0; i < RemainingChar; i++)
{
printf("%c", str1[i + strlen(str2) - 1]); //print the remaining part
}
}
return 0;
}
Here is how it run:
Input the first string:asdfghjkl
Input the second string:asd
Input the third string:qwe
qwe
fghjkl
There is an unexpected line break. what should I do to make it output like this:qwefghjkl?
The function fgets will also store the newline character '\n' at the end of the line into the string. If you don't want this newline character to be printed, then you must remove it before printing the string.
See the following question for several ways to remove the newline character:
Removing trailing newline character from fgets() input
Related
I try to get strings as many as the input value in c.
But a leading white space located first line is removed.
I had already use the fgets and scanset. I want the input and output to be the same.
fgets(str[i], 100, stdin);
scanf("%[^\n]%*c]", str);
Code
int n = 0;
scanf("%d\n", &n);
char str[10][100] = {0};
for (int i = 0; i < n; i++) {
fgets(str[i], 100, stdin);
}
Input
3
**
*
**
Output
**
*
**
What should I do?
You have to use getchar() after reading n because the newline character '\n' will remain in the input buffer and your fgets in for loop will read that and also remove \n from scanf.
Use following line of code:
int n = 0;
scanf("%d\n", &n);
getchar();
char str[10][100] = {0};
for (int i = 0; i < n; i++) {
fgets(str[i], 100, stdin);
}
remove the "\n" from scanf and add a getchar() to capture the newline.
scanf("%d", &n);
getchar();
This lab is trying to show the use of coder-defined functions to execute the code, but I'm trying to do it alternatively so when we actually are tested on it I won't be freaking out that I just copied the source code.
#define NotFound -1
#define WordSize 20
int stringSearch(char * string, char array, int * letter);
int main(void)
{
char * string = (char *) malloc(WordSize * sizeof(char));
char tester = '\0';
int index_tester = 0, i;
// do
// {
// printf("Enter a test string and character, enter q for the test string to exit.\n");
// printf("Test string: ");
// scanf("%s", string);
// while (getchar() != '\n') {}
// if (strcmp(string, "q") == 0) {
// break;
// }
// } // ----> Is it possible to do a while or for look instead? loop here?
printf("What is the test string you wish to enter: ?");
for (i = 0; i < sizeof(string); i++)
{
{
scanf("%c", &string[i]);
}
}
string[i] = '\0';
puts(string);
printf("Tester for the inputed string: ");
scanf("%c", &tester);
while (getchar() != '\n') {}
int ResultofSearch = stringSearch(string, tester, &index_tester);
if (ResultofSearch == NotFound)
{
printf("That letter is not foudn in the string, try again: ");
}
else {
printf("Character found at index %d.\n\n", index_tester);
}
return 0;
}
int stringSearch(char * string, char array, int * letter)
{
for (int i = 0; i < strlen(string); i++)
{
if (string[i] == array)
{
*letter = i;
return (Found);
}
}
return(NotFound);
}
When executing the code, I can put in the string, which I think is working fine, but it will automatically put in the search for some random letters immediately without prompting for the user input. I'm still a greenhorn to all this coding stuff so sorry in advance, any advice would be appreciated though
Apart from the issues pointed out in the comments there is some things you should improve:
char * string = (char *) malloc(WordSize * sizeof(char)); is the same as char * string = malloc(WordSize), but for a 20 word string we will need char * string = malloc(WordSize + 1)
This part of the code:
for (i = 0; i < Wordsize; i++) // already corrected
{
{
scanf("%c", &string[i]);
}
}
string[i] = '\0';
This will obligate you to always have a 19 character string. The cycle will not end until you do (you replace the 20th character with the null-terminator).
You can replace the whole thing with:
fgets(string, WordSize + 1, stdin);
And for good measure, discard the extra characters when the input is too big to fit the string.
int c;
while((c = fgetc(stdin)) !='\n' && c =! EOF); //discard until newline, for completion check for EOF return
This will allow a 20 character max size string but also for smaller ones.
Working sample
You should add required headers, use fgets() rather than scanf() and set tester_index to -1 rather than 0 which means found at index 0.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Found 1
#define NotFound 0
#define WordSize 20
int stringSearch(char * string, char array, int * letter);
int main(void)
{
char * string = (char *) malloc(WordSize * sizeof(char));
//char tester = '\0';
char tester[2] = {'\0', '\0'};
int index_tester = -1; // 0 means found # index 0
/* (...) */
printf("What is the test string you wish to enter: ?\n");
fgets(string, WordSize, stdin);
if (string[WordSize-1]=='\n')
string[WordSize-1]='\0';
puts(string);
printf("Tester for the inputed string: \n");
while (getchar() != '\n') {}
///scanf("%c", &tester[0]);
fgets(tester, 2, stdin);
int ResultofSearch = stringSearch(string, tester[0], &index_tester);
if (ResultofSearch == NotFound)
{
printf("That letter is not found in the string.\n");
}
else {
printf("Character found at index %d.\n\n", index_tester);
}
return 0;
}
int stringSearch(char * string, char c, int * index)
{ ... }
It's definitely not perfect but works more less expected way.
I am trying to find out how many characters are in the given array except blanks
but it's not working, k supposed to count blanks and substract them from i[characters + blanks] but it doesn't.
int i= 0;
int n= 0;
int k= 0;
char c[256] = {};
fgets(c ,256, stdin);
while(c[i] != '\0' ){
if(c[i] == ' '){
i++;
k++;
continue;}
i++;}
printf("%d",i-k);
Few observation, here
fgets(c ,256, stdin);
fgets() stores \n at the end of buffer if read. From the manual page of fgets()
If a newline is read, it is stored into the buffer.
A terminating null byte ('\0') is stored after the last character in
the buffer
Remove the trailing \n first and then iterate over it. For e.g
fgets(c, sizeof(c), stdin);
c[strcspn(c, "\n")] = 0; /* remove the trailing \n */
Also use of continue is not required here i.e you can achieve the task without using it. For e.g
int main(void) {
int i= 0;
int k= 0;
char c[256] = ""; /* fill whole array with 0 */
fgets(c, sizeof(c), stdin);
c[strcspn(c, "\n")] = 0; /* remove the trailing \n */
while(c[i] != '\0' ){ /* or just c[i] */
if(c[i] == ' ') {
k++; /* when cond is true, increment cout */
}
i++; /* keep it outside i.e spaces or not spaces
this should increment */
}
printf("spaces [%d] without spaces [%d]\n",k,i-k);
return 0;
}
I'm trying to create a program that checks if a given array/string is a palindrome or not and its not working. The program just prints "0" on every given array, even on palindromes.
int main()
{
char string[100]= {0};
char stringReverse[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
strcpy(stringReverse , string); // This function copies the scanned array to a new array called "stringReverse"
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// This while reverses the array and insert it to a new array called "stringReverse"
while(firstLetter < lastLetter)
{
temp = stringReverse[firstLetter];
stringReverse[firstLetter] = stringReverse[lastLetter];
stringReverse[lastLetter] = temp;
firstLetter++;
lastLetter--;
}
printf("%s %s", stringReverse, string);
if ( strcmp(stringReverse , string) == 0)
{
printf("1");
}
else
{
printf("0");
}
}
Lets say we implement a simple fun to do that
int check_palindrome (const char *s) {
int i,j;
for (i=0,j=strlen(s)-1 ; i<j ; ++i, --j) {
if (s[i] != s[j]) return 0; // Not palindrome
}
return 1; //Palindrome
}
I think this is far more simpler ;)
For the code posted in question:
Be aware of fgets(). It stops in the first '\n' or EOF and keeps the '\n' character.
So if you give radar for ex, the result string will be "radar\n", which doesn't match with "\nradar"
The Problem:
Let's say you enter the string RACECAR as input for your program and press enter, this puts a newline character or a '\n' in your buffer stream and this is also read as part of your string by fgets, and so your program effectively ends up checking if RACECAR\n is a palindrome, which it is not.
The Solution:
After you initialize lastLetter to strlen(string) - 1 check if the last character in your string (or the character at the lastLetter index is the newline character (\n) and if so, decrease lastLetter by one so that your program checks if the rest of your string (RACECAR) is a palindrome.
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// Add these 2 lines to your code
// Checks if the last character of the string read by fgets is newline
if (string[lastLetter] == '\n')
lastLetter--;
fgets adds a '\n' at the end.
So if the user entered "aba", string contains "aba\n".
reverseString contains "\naba".
So it doesn't match.
After the fgets, add this code
int l = strlen(string) - 1;
string[l] = 0;
This will strip out the '\n' at the end before copying it to reverseString.
That aside, you can do this whole program inplace without the need of a second buffer or strcpy or strlen calls.
You have several issues in your code:
first you forgot the last closing brace };
then you forgot to remove the trailing \n (or maybe also \r under Windows) in string;
you don't need to revert the string into a new string; a one-pass check is enough:
Here is a working code:
#include <stdio.h>
#include <string.h>
int main()
{
char string[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
while ((string[lastLetter]=='\n')||(string[lastLetter]=='\r')) {
lastLetter--;
}
// This while reverses the array and insert it to a new array called "stringReverse"
temp = 1;
while(firstLetter < lastLetter)
{
if (string[firstLetter] != string[lastLetter]) {
temp = 0;
break;
}
firstLetter++;
lastLetter--;
}
if ( temp )
{
printf("1");
}
else
{
printf("0");
}
}
You can do it by this simpleway also.
#include <stdio.h>
#include <string.h>
int main()
{
char string[10], revString[10];
printf("Enter string for reversing it...\n");
scanf("%s", string);
int stringLength = strlen(string);
for(int i = 0; string[i] != '\0'; i++, stringLength--)
{
revString[i] = string[stringLength - 1];
}
if(strcmp(string, revString) == 0)
printf("Given string is pelindrom\n");
else
printf("Given string is not pelindrom\n");
}
#include<stdio.h>
#include<string.h>`enter code here`
void fun(char *a);
int main ()
{
char p[100];
char *s=p;
printf("enter the string");
scanf("%[^\n]",s);
fun(s);
}
void fun(char *a)
{
if(*a && *a!='\n')
{
fun(a+1);
putchar(*a);
}
}
// use this approach better time complexity and easier work hope this helps
this is my first post in this forum so please be patient.
I need to make a short programm, where the user can enter 2 strings which should be attached afterwards.
I already got this code below (I am not allowed to use other "includes").
What I need to know is: How can I deny any spaces which the user will enter?
Example: 1. String "Hello " | 2. String "World" Result should be "HelloWorld" instead of "Hello World".
#include <stdio.h>
void main()
{
char eingabe1[100];
char eingabe2[100];
int i = 0;
int j = 0;
printf("Gib zwei Wörter ein, die aneinander angehängt werden sollen\n");
printf("1. Zeichenkette: ");
gets(eingabe1);
printf("\n");
printf("2. Zeichenkette: ");
gets(eingabe2);
printf("\n");
while (eingabe1[i] != '\0')
{
i++;
}
while (eingabe2[j] != '\0')
{
eingabe1[i++] = eingabe2[j++];
}
eingabe1[i] = '\0';
printf("Nach Verketten: ");
puts(eingabe1);
}
You have to filter out the spaces as you copy your strings.
You have two string indices, i for the first string and and j for the second string. You could make better use of these indices if you used i for the reading position (of both strings subsequently; you can "reuse" loop counters in independent loops) and j for the writing position.
Here's how. Note that the code attempts to prevent buffer overflow by only adding characters if there is space in the string. This check needs only to be done when copying the second string, because j <= i when you process the first string.
#include <stdio.h>
int main()
{
char str1[100] = "The quick brown fox jumps over ";
char str2[100] = "my big sphinx of quartz";
int i = 0;
int j = 0;
while (str1[i] != '\0') {
if (str1[i] != ' ') str1[j++] = str1[i];
i++;
}
i = 0;
while (str2[i] != '\0') {
if (str2[i] != ' ' && j + 1 < sizeof(str1)) str1[j++] = str2[i];
i++;
}
str1[j] = '\0';
printf("'%s'\n", str1);
return 0;
}
In addition to avoiding spaces between your two words, you also have to avoid the newline ('\n') character placed in the input buffer by the user pressing Enter. You can do that with a simple test after you have read the line with fgets() NOT gets(). gets() is no longer part of the standard C library and should not be used due to insecurity reasons. Plus fgets provides simple length control over the number of characters a user may enter at any time.
Below, you run into trouble when you read eingabe1. After the read, eingabe1 contains a '\n' character at its end. (as it would using any of the line-oriented input functions (e.g. getline(), fgets(), etc) To handle the newline, you can simply compare its length minus '1' after you loop over the string to find the nul character. e.g.:
if (eingabe1[i-1] == '\n') i--; /* remove trailing '\n', update i */
By simply reducing the index 'i', this will guarantee that the concatenation with eingabe2 will not have any spaces or newline characters between the words.
Putting the pieces together, and using fgets in place of the insecure gets, after #define MAX 100'ing a constant to prevent hardcoding your array indexes, you could come up with something similar to:
#include <stdio.h>
#define MAX 100
int main (void)
{
char eingabe1[MAX] = {0};
char eingabe2[MAX] = {0};
int i = 0;
int j = 0;
printf("Gib zwei Wörter ein, die aneinander angehängt werden sollen\n");
printf("1. Zeichenkette: ");
/* do NOT use gets - it is no longer part of the C library */
fgets(eingabe1, MAX, stdin);
putchar ('\n');
printf("2. Zeichenkette: ");
/* do NOT use gets - it is no longer part of the C library */
fgets(eingabe2, MAX, stdin);
putchar ('\n');
while (eingabe1[i]) i++; /* set i (index) to terminating nul */
if (i > 0) {
if (eingabe1[i-1] == '\n') i--; /* remove trailing '\n' */
while (i && eingabe1[i-1] == ' ') /* remove trailing ' ' */
i--;
}
while (eingabe2[j]) { /* concatenate string - no spaces */
eingabe1[i++] = eingabe2[j++];
}
eingabe1[i] = 0; /* nul-terminate eingabe1 */
printf("Nach Verketten: %s\n", eingabe1);
return 0;
}
Output
$ ./bin/strcatsimple
Gib zwei Wörter ein, die aneinander angehängt werden sollen
1. Zeichenkette: Lars
2. Zeichenkette: Kenitsche
Nach Verketten: LarsKenitsche
Let me know if you have any further questions. I have highlighted the changes with comments above.
/**
return: the new len of the string;
*/
int removeChar(char* string, char c) {
int i, j;
int len = strlen(string)+1; // +1 to include '\0'
for(i = 0, j = 0 ; i < len ; i++){
if( string[i] == c )
continue; // avoid incrementing j and copying c
string[ j ] = string[ i ]; // shift characters
j++;
}
return j-1; // do not count '\0';
}
int main(){
char str1[] = "sky is flat ";
char str2[100] = "earth is small ";
strcat( str2, str1 );
printf("with spaces:\n\t'%s'\n", str2) ;
removeChar(str2, ' ');
printf("without spaces:\n\t'%s'\n", str2 );
}
/**
BONUS: this will remove many characters at once, eg "\n \r\t"
return: the new len of the string;
*/
int removeChars(char* string, char *chars) {
int i, j;
int len = strlen(string);
for(i = 0, j = 0 ; i < len ; i++){
if( strchr(chars,string[i]) )
continue; // avoid incrementing j and copying c
string[ j ] = string[ i ]; // shift characters
j++;
}
string[ j ]=0;
return j;
}
Thank you everyone for all the answers.
I got the solution now.
I read some advices from you and will try to remember for the future.
See the code below:
(Excuse me for the strange names for the variables, I use german words)
A few notices:
I am not allowed to use library functions
I am not allowed to use fgets for some reasons as a trainee
#include <stdio.h>
void main()
{
char eingabe1[100];
char eingabe2[100];
int i = 0;
int j = 0;
printf("gib zwei wörter ein, die aneinander angehängt werden sollen\n");
printf("1. zeichenkette: ");
gets(eingabe1);
printf("\n");
printf("2. zeichenkette: ");
gets(eingabe2);
printf("\n");
//Attach Strings
while (eingabe1[i] != '\0')
{
i++;
}
while (eingabe2[j] != '\0')
{
eingabe1[i++] = eingabe2[j++];
}
//Remove Space
eingabe1[i] = '\0';
i = 0;
j = 0;
while (eingabe1[i] != '\0')
{
if (eingabe1[i] != 32)
{
eingabe2[j++] = eingabe1[i];
}
i++;
}
eingabe2[j] = '\0';
printf("Nach verketten: ");
puts(eingabe2);
}
Sounds like homework to me.
I just wanted to mention that you probably shouldn't use sizeof() on strings these days because there may be multibyte characters in there. Use strlen() instead. The only time sizeof() would be appropriate is if you're going to malloc() a certain number of bytes to store it.
I write little loops fairly often to do low level text stuff one character at a time, just be aware that strings in C usually have a 0 byte at the end. You have to expect to encounter one and be sure you put one on the output. Space is 0x20 or decimal 32 or ' ', it's just another character.