I'm trying to print the longest word in string but the loop is not running, I couldn't find a solution for this one.
char str[50];
int i = 0, count = 0, numOfWords = 0, place;
printf("Please enter a sentence: ");
gets(str);
while (str[i] != '\0') {
if (str[i] != ' ') {
numOfWords++;
if (str[i + 1] == ' ') {
if (numOfWords > count) {
count = numOfWords;
place = i + 1 - numOfWords;
numOfWords = 0;
}
}
}
i++;
}
puts(str);
printf("%d", count);
printf("The word is:\n");
for (i = place; i < numOfWords; i++)
printf("%c\n", str[i]);
getch();
You should use count to determine how many times the last loop should be taken.
You should also process the last word.
Try this:
#include <stdio.h>
#include <string.h>
/* This implementation is simple, but maximum readable length is decreased by 1 */
char* safer_gets(char* s, size_t max){
char* lf;
if (fgets(s, max, stdin) == NULL) return NULL;
if ((lf = strchr(s, '\n')) != NULL) *lf = '\0'; /* remove the newline character */
return s;
}
int main(void){
char str[51];
int i = 0, count = 0, numOfWords = 0, place = 0;
printf("Please enter a sentence: ");
safer_gets(str, sizeof(str));
while (str[i] != '\0')
{
if (str[i] != ' ')
{
numOfWords++;
if (str[i + 1] == ' ' || str[i + 1] == '\0')
{
if (numOfWords > count)
{
count = numOfWords;
place = i +1- numOfWords;
numOfWords = 0;
}
}
}
i++;
}
puts(str);
printf("%d", count);
printf("The word is:\n");
for (i = 0; i < count; i++)
printf("%c", str[place + i]);
putchar('\n');
return 0;
}
Related
Using the code below it only reads one char and does not convert morse to letter. My idea was to create a string of one morse "letter" and put it in the convert function, however only 1 char is being read since I am only seeing a single 1 printed on the screen after the string itself is printed. The string only consists of '-' , '.' , ' '. I was wondering if anyone knows what the solution might be.
char convertToLetter(M* data, char word[10]) {
int size = 0;
char correct;
while (size < 60)
{
int compare = strcmp(word, data->morse);
if (compare == 0) {
correct = data->letter;
}
data++;
size++;
}
correct = '\0';
return correct;
}
int main(){
//some code here for opening a file.
char curSent[200];
char letter[6] = "";
int i = 0;
char* fullString = (char*)malloc(1000 * sizeof(char));
fullString[0] = '\0';
while (fgets(curSent, 200, inFile) != NULL) {
if (curSent[0] != '\n') {
curSent[strlen(curSent) - 1] = '\0';
strcat_s(fullString,1000, curSent);
}
else {
printf("%s", fullString);
printf("\n\n");
int j = 0;
while (i < strlen(fullString)) {
if (fullString[i] != ' ') {
fullString[i] = letter[j];
i++;
j++;
printf("%d \n", 1);
}else if (fullString[i + 1] == ' ' && fullString[i] == ' ') {
printf("%d", 2);
printf(" %c", convertToLetter(dictionary, letter));
memset(letter, 0, strlen(letter));
j = 0;
i = i + 2;
}else if (fullString[i] == ' ') {
printf("%d", 3);
printf("%c", convertToLetter(dictionary, letter));
memset(letter, 0, strlen(letter));
j = 0;
i = i++;
}
}
memset(fullString, 0, strlen(fullString));
i = 0;
}
}
//printf("%s", fullString);
getchar();
return 0;
}
I was trying this pattern matching method in C but whenever I give all the input, the vscode terminal waits for a while and just stops the program without any warnings/message. Can anyone point to what is wrong here?
#include <stdio.h>
#include <string.h>
int main()
{
char STR[100], PAT[100], REP[100], ANS[100];
int i, m, j, k, flag, slP, slR, len;
i = m = k = j = flag = len = 0;
printf("\nMain String: ");
gets(STR);
printf("\nPattern String: ");
gets(PAT);
slP = strlen(PAT);
printf("\nReplace String: ");
gets(REP);
slR = strlen(REP);
while (STR[i] != '\0')
{
if (STR[i] = PAT[j])
{
len = 0;
for (k = 0; k < slP; k++)
{
if (STR[k] = PAT[k])
len++;
}
if (len == slP)
{
flag = 1;
for (k = 0; k < slR; k++, m++)
ANS[m] = REP[k];
}
}
else
{
ANS[m] = STR[i];
m++;
i++;
}
}
if (flag == 0)
{
printf("\nPattern not found!");
}
else
{
ANS[m] = '\0';
printf("\nResultant String: %s\n", ANS);
}
return 0;
}
There are multiple problems in the code:
using gets() is risky, this function was removed from the C Standard because it cannot be used safely.
if (STR[i] = PAT[j]) copied the pattern to the string. You should use:
if (STR[i] == PAT[j])
similarly, if (STR[k] = PAT[k]) is incorrect. You should compare PAT[k] and STR[i + k]:
if (STR[i + k] == PAT[k])
you should test for buffer overflow for the output string as replacing a short string by a larger one may produce a string that will not fit in ANS
you do not increment i properly.
Here is a modified version:
#include <stdio.h>
int getstr(const char *prompt, char *dest, int size) {
int c, len = 0;
printf("%s", prompt);
while ((c = getchar()) != EOF && c != '\n') {
if (len + 1 < size)
dest[len++] = c;
}
if (size > 0)
dest[len] = '\0';
printf("\n");
if (c == EOF && len == 0)
return -1;
else
return len;
}
int main() {
char STR[100], PAT[100], REP[100], ANS[100];
int i, m, k, flag;
if (getstr("Main String: ", STR, sizeof STR) < 0)
return 1;
if (getstr("Pattern String: ", PAT, sizeof PAT) < 0)
return 1;
if (getstr("Replace String: ", REP, sizeof REP) < 0)
return 1;
i = m = flag = 0;
while (STR[i] != '\0') {
if (STR[i] == PAT[0]) { // initial match
// compare the rest of the pattern
for (k = 1; PAT[k] != '\0' && PAT[k] == STR[i + k]; k++)
continue;
if (PAT[k] == '\0') { // complete match
flag = 1;
// copy the replacement string
for (k = 0; REP[k] != '\0'; k++) {
if (m + 1 < sizeof ANS)
ANS[m++] = REP[k];
}
i += k; // skip the matching characters
continue;
}
}
// otherwise copy a single character
if (m + 1 < sizeof ANS)
ANS[m++] = STR[i];
i++;
}
ANS[m] = '\0';
if (flag == 0) {
printf("Pattern not found!\n");
} else {
printf("Resultant String: %s\n", ANS);
}
return 0;
}
I have a problem with this code which is supposed to make a reverse sentence.
Example:
Input
Hi my name is Robert
Output
Robert is name my Hi
#include <stdio.h>
#define LEN 50
int main(void)
{
char input, terminator = 0, sentence[LEN+1] = {0};
int i, j, last_space = LEN + 1, posc=0;;
int pos[]={0};
printf("\nEnter a sentence: ");
for (i = 0; (input = getchar()) != '\n'; i++)
{
if(input== ' '){
pos[posc]=i;
posc++;
}
if (input == '.' || input == '?' || input == '!')
{
last_space = i;
terminator = input;
break;
}
sentence[i] = input;
}
if (terminator == 0)
{
printf("Sentence needs a terminating character. (./?/!)\n\n");
return 0;
}
printf("Reversal of sentence: ");
for (i = last_space; i > 0; i--)
{
if (sentence[i] == ' ')
{
for (j = i + 1; j != last_space; j++)
{
putchar(sentence[j]);
}
last_space = i;
putchar(sentence[i]);
}
}
while (sentence[i] != '\0' && sentence[i] != ' ')
{
putchar(sentence[i++]);
}
printf("%c\n\n", terminator);
for(int i=sizeof(pos)-1; i>0; i--){
printf("%.*s", sentence[pos[i-1]], sentence[pos[i]]);
}
printf("%c\n\n", terminator);
return 1;
}
This keeps crashing because of the method at the bottom here:
printf("%c\n\n", terminator);
for(int i=sizeof(pos)-1; i>0; i--){
printf("%.*s", sentence[pos[i-1]], sentence[pos[i]]);
}
printf("%c\n\n", terminator);
return 1;
}
Can someone help me fix this snippet of code for me so that both methods work when run? Thanks.
The array of size 1 is created by the line:
int pos[]={0};
And later you are accessing over the array's limit here:
if(input== ' '){
pos[posc]=i;
posc++;
}
The behaviour is undefined after that. The same mistake presents in the code you've mentioned due to sizeof returns the size in bytes, not just amount of elements.
There is a simplest way to do it,
you just have to write a function who will write the last word of the sentence first, then the second and goes on ..
There you can find a working code
#include <unistd.h>
//This function print the last word or a space
static int print_last(const char *str, int len)
{
int i = 0;
while (len > 0 && str[len] == ' ')
len--;
while (i <= len && str[len - i] != ' ')
i++;
write(1, str + len - i + 1, i);
while (len > 0 && str[len] == ' ')
len--;
if (i < len)
write(1, " ", 1);
return (len - i);
}
int main(int ac, char **av)
{
int len = 0;
if (ac == 2)
{
while (av[1][len])
len++;
len--;
while (len > 0)
len = print_last(av[1], len);
}
write(1, "\n", 1);
return (0);
}
and there, once compiled (to compile --> clang yourFileName.c) , you can call the program like so
./youCompiledProgram 'the sentance you want to be inverted'
I have school task. To reverse each word in sentence, so example :
Input: Fried chicken, fried duck.
Output: deirF nekcihc, deirf kcud.
So except dot and comma it's not reversed.
The first code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int i, n, titik = 0, coma = 0;
char s[5001];
char c[5001];
char *tok;
scanf("%[^\n]s", s);
if (s[0] == ' ')
printf(" ");
tok = strtok(s, " ");
while (tok != NULL) {
strcpy(c, tok);
n = strlen(c);
for (i = n; i >= 0; i--) {
if (c[i] == ',') {
coma = 1;
} else
if (c[i] == '.') {
titik = 1;
} else
printf("%c", c[i]);
}
if (coma) {
printf(",");
coma = 0;
} else
if (titik){
printf(".");
titik = 0;
}
tok = strtok(NULL," ");
if (tok == NULL)
printf("\n");
else
printf(" ");
}
}
Second code is
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
int i, j, n, prana = 0, titik = 0, coma = 0, end = 0;
char s[5001];
scanf("%[^\n]s", s);
n = strlen(s);
for (i = 0; i <= n; i++) {
if (isspace(s[i]) || iscntrl(s[i])) {
if (iscntrl(s[i]))
end = 1;
for (j = i - 1; j >= prana; j--) {
if (s[j] == '.') {
titik = 1;
} else
if (s[j] == ',') {
coma = 1;
} else
printf("%c", s[j]);
}
prana = i + 1;
if (titik) {
titik = 0;
if (end)
printf(".");
else
printf(". ");
} else
if (coma) {
coma = 0;
if (end)
printf(",");
else
printf(", ");
} else {
if (end)
printf("");
else
printf(" ");
}
}
}
printf("\n");
return 0;
}
Why the second code is accepted in test case?, but first code is not.
I tested the result it's same. Really identical in md5 hash.
The output of the two codes id different, because you print the terminating null character for each token in the first code. This loop:
for (i = n; i >=0 ; i--) ...
will have i == n in its first iteration. For a C string of length n, s[n] is the terminating null. This character may not show in the console, but it is part of the output.
To fix the loop, you could start with i = n - 1, but C uses inclusive lower bounds and exclusive upper bounds, and a more idomatic loop syntax is:
i = n;
while (i-- > 0) ...
Not related to your question at hand, but your codes are rather complicated, because they rely on many assumptions: words separated by spaces; only punctuation is comma or stop; repeated punctuation marks are ignored, special case for last word.
Here's a solution that treats all chunks of alphabetic characters plus the apostrophe as words and reverses them in place:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
void reverse(char *str, int i, int j)
{
while (i < j) {
int c = str[--j];
str[j] = str[i];
str[i++] = c;
}
}
int main()
{
char str[512];
int begin = -1;
int i;
if (fgets(str, sizeof(str), stdin) == NULL) return -1;
for (i = 0; str[i]; i++) {
if (isalpha((unsigned char) str[i]) || str[i] == '\'') {
if (begin == -1) begin = i;
} else {
if (begin != -1) {
reverse(str, begin, i);
begin = -1;
}
}
}
printf("%s", str);
return 0;
}
I'm trying to split a sentence the user inputs to an array of words so I can later manipulate the words separately as strings.
The code is compiling but prints only garbage after the user input.
I tried debugging but don't see the problem. Can someone help me fix it?
#include <stdio.h>
#include <string.h>
int main() {
char str[1000];
int i = 0;
char rev[1000][1000];
int r = 0;
puts("Enter text:");
gets(str);
int k, length = 0;
printf_s("So the words are:\n");
while (str[i] != '\0') {
if (str[i] == ' ') {
k = i - length;
do {
rev[r][k] = (str[k]);
k++;
} while (str[k] != ' ');
printf(" ");
length = (-1);
r++;
} else
if (str[i + 1] == '\0') {
k = i - length;
do {
rev[r][k] = (str[k]);
k++;
} while (str[k] != '\0');
length = 0;
r++;
}
length++;
i++;
}
for (int r = 0; r < 1000; r++)
printf("%s ", rev[r]);
return 0;
}
fix like this
#include <stdio.h>
int main(void) {
char str[1000];
char rev[1000][1000];
puts("Enter text:");
fgets(str, sizeof str, stdin);//Use fgets instead of gets. It has already been abolished.
int r = 0;
int k = 0;
for(int i = 0; str[i] != '\0'; ++i){
if (str[i] == ' ' || str[i] == '\n'){//is delimiter
if(k != 0){
rev[r++][k] = '\0';//add null-terminator and increment rows
k = 0;//reset store position
}
} else {
rev[r][k++] = str[i];
}
}
if(k != 0)//Lastly there was no delimiter
rev[r++][k] = '\0';
puts("So the words are:");
for (int i = 0; i < r; i++){
printf("%s", rev[i]);
if(i < r - 2)
printf(", ");
else if(i == r - 2)
printf(" and ");
}
return 0;
}
Replace you declaration
char rev[1000][1000];
with
char * rev[1000]; // We will need pointers only
int i = 0; // Index to previous array
and all your code after
puts( "Enter text:" );
with this:
fgets( str, 998, stdin ); // Safe way; don't use gets(str)
const char delim[] = ",; "; // Possible delimiters - comma, semicolon, space
char *word;
/* Get the first word */
word = strtok( str, delim );
rev[i++] = word;
/* Get the next words */
while( word != NULL )
{
word = strtok( NULL, delim );
rev[i++] = word;
}
/* Testing */
for (int r = 0; r < i - 1; r++)
printf( "%s\n", rev[r] );
return 0
}
As you can see, all dirty work is done with the strtok() function ("string to tokens") which walks through other and other words ("tokens"), recognizing them as delimited by one or more characters from the string delim.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_spaces(char *str)
{
if (str == NULL || strlen(str) <= 0)
return (0);
int i = 0, count = 0;
while (str[i])
{
if (str[i] == ' ')
count++;
i++;
}
return (count);
}
int count_char_from_pos(char *str, int pos)
{
if (str == NULL || strlen(str) <= 0)
return 0;
int i = pos, count = 0;
while (str[i] && str[i] != ' ')
{
count++;
i++;
}
return count;
}
char **get_words(char *str)
{
if (str == NULL || strlen(str) <= 0)
{
printf("Bad string inputed");
return NULL;
}
int i = 0, j = 0, k = 0;
char **dest;
if ((dest = malloc(sizeof(char*) * (count_spaces(str) + 1))) == NULL
|| (dest[0] = malloc(sizeof(char) * (count_char_from_pos(str, 0) + 1))) == NULL)
{
printf("Malloc failed\n");
return NULL;
}
while (str[i])
{
if (str[i] == ' ') {
dest[j++][k] = '\0';
if ((dest[j] = malloc(sizeof(char) * (count_char_from_pos(str, i) + 1))) == NULL)
{
printf("Malloc failed\n");
return NULL;
}
k = 0;
}
else {
dest[j][k++] = str[i];
}
i++;
}
dest[j][k] = 0;
dest[j + 1] = NULL;
return dest;
}
int main(void) {
char *line = NULL;
size_t n = 0;
getline(&line, &n, stdin);
printf("%s\n", line);
line[strlen(line) - 1] = 0;
printf("%s\n", line);
char **tab = get_words(line);
int i = 0;
while (tab[i])
{
printf("%s\n", tab[i++]);
}
}
here is a long but fully working example
get the user input
then send it to get_words function. It will get the number of words, the number of characters for each words, allocate everything in memory and writes chars then return it. You get a char ** and prints it just tested it it works
If you wish to split a string into an array of strings, you should consider the strtok function from #include <string.h>. The strtok function will the split the string on the given delimiter(s). For your case, it would the " ".
Using the strtok example from Tutorials Point:
#include <string.h>
#include <stdio.h>
int main(){
char str[80] = "This is - www.tutorialspoint.com - website";//The string you wish to split
const char s[] = "-";//The thing you want it to split from. But there is no need to this.
char *token;//Storing the string
/* get the first token */
token = strtok(str, s);//Split str one time using the delimiter s
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );//Print the string
token = strtok(NULL, s);//Split the string again using the delimiter
}
return(0);
}