Get Usernames from String in C - c

I am writing a function that is supposed to get an array with a tweet inside it and an empty array which should be filled with usernames that are in the tweet starting with '#' each in its own line. The usernames in the username array should be without the '#'.
This is what I have so far, but this version only stores one username and doesn't even put a new line behind it, and I don't know why.
It's probably a logic mistake?
void extract_username(char *tweet, char *user){
int j = 0;
int z = 0;
for(int i = 0; i<strlen(tweet); i++){
if(tweet[i] == '#'){
z = i+1;
while(tweet[z] != ' '){
user[j] = tweet[z];
z++;
j++;
}
j++;
user[j] = '\n';
}
}
}
extract_username gets called in the main like this
int main(){
char tweet[281];
char user[281]; //for example #user1 hello #user2
printf("Please enter a tweet (max. 280 symbols): \n");
fgets(tweet, 281, stdin);
extract_usename(tweet, user);
printf("%s", user);
return 0;
}

Making the fewest changes possible, change the condition to while (tweet[z] != ' ' && tweet[z] != 0) and add the newline with user[j++] = '\n'; Probably best to explicitly add the NUL terminator at the end with user[j] = 0; as well.
void extract_username(char* tweet, char* user) {
int j = 0;
int z = 0;
for (int i = 0; i < strlen(tweet); i++) {
if (tweet[i] == '#') {
z = i + 1;
while (tweet[z] != ' ' && tweet[z] != 0) {
user[j] = tweet[z];
z++;
j++;
}
user[j++] = '\n';
}
}
user[j] = 0;
}

Related

turning morse into english from a txt file in C, only iterates 1 char in the string before stopping

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;
}

Print "no solution" if there's no input

I tried modifying this code to print
no solution
if there is no input by user. That is, if I run the program and simply press enter it should print no solution. I added the code that's meant to do that to check if the string length is 0 then print but it doesn't work
#include <stdio.h>
#include <string.h>
int main()
{
char str1[100];
char newString[10][10];
int i, j, ctr;
fgets(str1, sizeof str1, stdin);
j = 0; ctr = 0;
if (strlen(str1) == 0) {
printf_s("no solution");
}
else
for (i = 0; i <= (strlen(str1)); i++)
{
// if space or NULL found, assign NULL into newString[ctr]
if (str1[i] == ' ' || str1[i] == '\0')
{
newString[ctr][j] = '\0';
ctr++; //for next word
j = 0; //for next word, init index to 0
}
else if (str1[i] == '.' || str1[i] == ',')
{
newString[ctr][j] = '\0';
ctr--; //for next word
j = - 1;
}
else
{
newString[ctr][j] = str1[i];
j++;
}
}
printf("\n\n");
for (i = 0; i < ctr; i++)
printf(" %s\n", newString[i]);
return 0;
}
fgets() will add a new line to your string (see this link for more information) which means when you simply press enter your string length(since your string includes \n) is 1 , you should say:
if (strlen(str1) == 1) {
printf_s("no solution");
// it's better to add a return 0; here if you don't want to continue the program
}
or use this instead:
if (!strcmp(str1,"\n")) {
printf_s("no solution");
}

passing char array to function from scanf in c

I have following function in c code
void analyze_text(char text[]) {
...
for (int i = 0; i < text_length || text[i] != '\0'; i++) {
...
}
}
In main function i would like to pass some string to it. If i do something like this
char text[4000] = "some text here";
analyze_text(text);
this is cool and do the goal, but i would like to have some user input present and I am not sure how to get char[] out of it. I tried following 2 and none of them seemed to work:
char text[4000];
scanf("%s",text);
analyze_text(text);
OR
char text[4000];
int c;
int count=0;
c = getchar();
count = 0;
while ((count < 4000) && (c != EOF)) {
text[count] = c;
++count;
c = getchar();
}
analyze_text(text);
I know that the first one should return pointer to char array, but second one should return char array itself, or not?
Its been like 10 years since i havent been working with c/c++. Can anybody give me some hint please?
update (whole function):
void analyze_text(char text[]) {
int printable_text_length = 0;
int text_length = strlen(text);
int word_count = 0;
int sentence_count = 0;
int in_sentence = 0;
int in_word = 0;
int count[ASCII_SIZE] = { 0 };
for (int i = 0; i < text_length || text[i] != '\0'; i++) {
int c = text[i];
if (!isspace(c)) {
printable_text_length++;
}
if (isalpha(c)) {
in_word = 1;
in_sentence = 1;
count[tolower(c)]++;
}
if (text[i] == ' ' && text[i + 1] != ' ' && in_word==1) {
word_count++;
in_word = 0;
}
if (text[i] == '.' && in_sentence==1) {
sentence_count++;
in_sentence = 0;
}
}
if (in_word == 1) { word_count++; }
if (in_sentence == 1) { sentence_count++; }
char charIndexes[ASCII_SIZE];
for (int i = 97; i <= 122; i++) {
charIndexes[i] = i;
}
for (int i=97; i <= 122; i++) {
for (int j = i + 1; j <= 122; j++) {
if (count[i] > count[j]) {
int temp = count[j];
count[j] = count[i];
count[i] = temp;
int temp2 = charIndexes[j];
charIndexes[j] = charIndexes[i];
charIndexes[i] = temp2;
}
}
}
...printf...
}
The issue with
char text[4000];
scanf("%s",text);
analyze_text(text);
is that scanf identifies space-separated chunks, so you'll only read the first one.
In order to read up to a whole line from the user, try fgets:
char text[4000];
fgets(text, 4000, stdin);
analyze_text(text);
You may want to check the return value of fgets for error detection.
You can use dyanamic array of char to pass it into the function.
Here is the code
#include <stdio.h>
#include <stdlib.h>
void analyze_text(char* text) {
for (int i = 0; text[i] != '\0'; i++) {
printf("%c\n",text[i] );
}
}
int main() {
char* text = (char *)malloc(4000 * sizeof(char));
scanf("%s", text);
analyze_text(text);
return 0;
}
and here is the output with input = 'abhishek'
a
b
h
i
s
h
e
k
remember that strlen in dyanamc array will not give the length of input array.

How to get words out of a string and put them in an string array ? In C

I basically have a sentence in a string and want to break it down word per word. Every word should go into an array of strings. I am not allowed to use strtok. I have this code but it doesn't work. Can someone help?
There is for sure something similar in the internet but I couldn't find anything...
int main(){
char s[10000]; // sentence
char array[100][100]; // array where I put every word
printf("Insert sentence: "); // receive the sentence
gets(s);
int i = 0;
int j = 0;
for(j = 0; s[j] != '\0'; j++){ // loop until I reach the end
for(i = 0; s[i] != ' '; i++){ // loop until the word is over
array[j][i] = s[i]; // put every char in the array
}
}
return 0;
}
Every word should go into an array of strings. I am not allowed to use
strtok.
Interesting problem which could be resolved in a compact algorithm.
It handles multiple spaces and punctuation marks specified in check(char c).
The most difficult part of the problem is to properly handle corner cases. We may have situation when words are longer more than WORD_LEN length or the number of words exceeds the capacity of the array.
Both cases are properly handled. The algorithm truncates the excessive words and parses only to the capacity of the array.
(BTW. Do not use gets: Why is the gets function so dangerous that it should not be used?)
Edit: The fully tested find_tokens function has been presented.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_LEN 3 // 100 // MAX WORD LEN
#define NR_OF_WORDS 3 // 100 // MAX NUMBER OF WORDS
#define INPUT_SIZE 10000
int is_delimiter(const char * delimiters, char c) // check for a delimiter
{
char *p = strchr (delimiters, c); // if not NULL c is separator
if (p) return 1; // delimeter
else return 0; // not a delimeter
}
int skip(int *i, char *str, int skip_delimiters, const char *delimiters)
{
while(1){
if(skip_delimiters) {
if( (str[(*i)+1] =='\0') || (!is_delimiter(delimiters, str[(*i)+1])) )
break; // break on nondelimeter or '\0'
else (*i)++; // advance to next character
}
else{ // skip excess characters in the token
if( is_delimiter(delimiters, str[(*i)]) )
{
if( (str[(*i)+1] =='\0') || !is_delimiter(delimiters, str[(*i)+1]) )
break; // break on non delimiter or '\0'
else (*i)++; // skip delimiters
}
else (*i)++; // skip non delimiters
}
}
if ( str[(*i)+1] =='\0') return 0;
else return 1;
}
int find_tokens(int max_tokens, int token_len, char *str, char array[][token_len+1], const char *delimiters, int *nr_of_tokens)
{
int i = 0;
int j = 0;
int l = 0;
*nr_of_tokens = 0;
int status = 0; // all OK!
int skip_leading_delimiters = 1;
int token = 0;
int more;
for(i = 0; str[i] != '\0'; i++){ // loop until I reach the end
// skip leading delimiters
if( skip_leading_delimiters )
{
if( is_delimiter( delimiters, str[i]) ) continue;
skip_leading_delimiters = 0;
}
if( !is_delimiter(delimiters,str[i]) && (j < token_len) )
{
array[l][j] = str[i]; // put char in the array
//printf("%c!\n", array[l][j] );
j++;
array[l][j] = 0;
token = 1;
}
else
{
//printf("%c?\n", str[i] );
array[l][j] = '\0'; // token terminations
if (j < token_len) {
more = skip(&i, str, 1, delimiters); // skip delimiters
}
else{
more = skip(&i, str, 0, delimiters); // skip excess of the characters in token
status = status | 0x01; // token has been truncated
}
j = 0;
//printf("more %d\n",more);
if(token){
if (more) l++;
}
if(l >= max_tokens){
status = status | 0x02; // more tokens than expected
break;
}
}
}
if(l>=max_tokens)
*nr_of_tokens = max_tokens;
else{
if(l<=0 && token)
*nr_of_tokens = 1;
else
{
if(token)
*nr_of_tokens = l+1;
else
*nr_of_tokens = l;
}
}
return status;
}
int main(void){
char input[INPUT_SIZE+1]; // sentence
char array[NR_OF_WORDS][WORD_LEN+1]; // array where I put every word, remeber to include null terminator!!!
int number_of_words;
const char * delimiters = " .,;:\t"; // word delimiters
char *p;
printf("Insert sentence: "); // receive the sentence
fgets(input, INPUT_SIZE, stdin);
if ( (p = strchr(input, '\n')) != NULL) *p = '\0'; // remove '\n'
int ret = find_tokens(NR_OF_WORDS, WORD_LEN, input, array, delimiters, &number_of_words);
printf("tokens= %d ret= %d\n", number_of_words, ret);
for (int i=0; i < number_of_words; i++)
printf("%d: %s\n", i, array[i]);
printf("End\n");
return 0;
}
Test:
Insert sentence: ..........1234567,,,,,,abcdefgh....123::::::::::::
tokens= 3 ret= 1
0: 123
1: abc
2: 123
End
You are not '\0'-terminating the strings and you are scanning the source from
the beginning every time you've found a empty character.
You only need one loop and, the inner loop and the condition must be s[i] != 0:
int j = 0; // index for array
int k = 0; // index for array[j]
for(i = 0; s[i] != '\0'; ++i)
{
if(k == 99)
{
// word longer than array[j] can hold, aborting
array[j][99] = 0; // 0-terminating string
break;
}
if(j == 99)
{
// more words than array can hold, aborting
break;
}
if(s[i] == ' ')
{
array[j][k] = 0; // 0-terminating string
j++; // for the next entry in array
k = 0;
} else
array[j][k++] = s[i];
}
Note that this algorithm doesn't handle multiple spaces and punctuation marks.
This can be solved by using a variable that stores the last state.
int j = 0; // index for array
int k = 0; // index for array[j]
int sep_state = 0; // 0 normal mode, 1 separation mode
for(i = 0; s[i] != '\0'; ++i)
{
if(k == 99)
{
// word longer than array[j] can hold, aborting
array[j][99] = 0; // 0-terminating string
break;
}
if(j == 99)
{
// more words than array can hold, aborting
break;
}
// check for usual word separators
if(s[i] == ' ' || s[i] == '.' || s[i] == ',' || s[i] == ';' || s[i] == ':')
{
if(sep_state == 1)
continue; // skip multiple separators
array[j][k] = 0; // 0-terminating string
j++; // for the next entry in array
k = 0;
sep_state = 1; // enter separation mode
} else {
array[j][k++] = s[i];
sep_state = 0; // leave separation mode
}
}
As you can see, using the sep_state variable I'm able to check if multiple
separators come one after the other and skips subsequent separators. I also
check for common punctuation marks.
#include <stdio.h>
int main()
{
char s[10000]; // sentence
char array[100][100]; // array where i put every word
printf("Insert sentence: "); // receive the sentece
gets(s);
printf("%s",s);
int i = 0;
int j = 0;
int k = 0;
for(j = 0; s[j] != '\0'; j++){ // loop until i reach the end
if ( s[j] != ' ' || s[j] == '\0' )
{
array[i][k] = s[j];
k++;
}
else {
i++;
k = 0;
}
}
return 0;
}
please note that the gets function is very unsafe and shouldn't in any case be used, use scanf or fgets instead

Changing word in string with another word in C

I am looking for a way to change words in string.
I want to change word to another word which have more symbols than first word.
First I count the symbols of the word which i want to change with another one,
than I count how many this word is in the text which is in my program as a char array(string) and now i want to change this word with the word which has more symbols.
There is the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
Start:
printf("This program can change word or symbols combanation in text\n\n");
char text[550] = "There was a grocery shop in a town. Plenty of mice lived in that grocery shop.\nFood was in plenty for them. hey also wasted the bread\nbiscuits and fruits of the shop.\nThe grocer got really worried. So, he thought I should buy a cat\nand let it stay at the grocery. Only then I can save my things.\nHe bought a nice, big fat cat and let him stay there. The cat had a nice\nime hunting the mice and killing them.\nThe mice could not move freely now. They were afraid that\n\n";
printf("%s\n", text);
int symbols_in_text = 0;
for (int f = 0;f < 550;f++)
{
if (text[f])
{
symbols_in_text++;
}
else
{
break;
}
}
printf("Text has %i symbols\n\n", symbols_in_text);
char b[15];
printf("Which word would you like to chenge in text above?\n(Maximum quantity of Symbols is 15)\nType word or some symbol(s)\n--->>");
cin >> b;
int word_symbols=0;
for (int a = 0;a < 15;a++)
{
if (b[a])
{
word_symbols++;
}
else
{
break;
}
}
printf("Word which you have entered has %i symbols\n", word_symbols);
int word_in_text = 0;
for (int i = 0; i < 550 - word_symbols; i++)
{
int found = 1;
for (int j = 0; j < word_symbols; j++)
{
if (b[j] != text[i + j])
{
found = 0;
break;
}
}
if (found && text[i + word_symbols]==' ')
{
word_in_text++;
}
}
printf("Founded %i %s as the word an is Not the some part of the other word\n", word_in_text,b);
if (word_in_text != 0)
{
char input_word[15];
printf("Enter the word which you want to insert for first entered word\nWarning:You have to enter the world which have %i symbols\n--->>", word_symbols);
cin >> input_word;
int in_word_symbols = 0;
for (int a = 0;a < 15;a++)
{
if (input_word[a])
{
in_word_symbols++;
}
else
{
break;
}
}
printf("The word which you have entered has %i symbols\n\n", in_word_symbols);
if (word_symbols == in_word_symbols)
{
for (int i = 0; i < 550 - word_symbols; i++)
{
int found = 1;
for (int j = 0; j < word_symbols; j++)
{
if (b[j] != text[i + j])
{
found = 0;
break;
}
}
if (found != 0 && text[i + word_symbols] == ' ')
{
for (int j = 0; j < in_word_symbols; j++)
{
text[i + j] = input_word[j];
}
}
}
printf("The result is--->>\n%s\n\n//////////////////////////////////////////END OF////////////////////////////////////////\n\n", text);
}
else if (in_word_symbols > word_symbols)
{
int text_char_index = 0;
step1:
for (int count = 0; count < 550 - word_symbols; count++)
{
text_char_index++;
int found = 1;
for (int j = 0; j < word_symbols; j++)
{
if (b[j] != text[count + j])
{
found = 0;
break;
}
if (found != 0 && text[count + word_symbols] == ' ')
{
count = text_char_index-1;
goto index_changing;
insert:
for (int c = 0; c < in_word_symbols; c++)
{
text[count + c] = input_word[c];
}
if (count > 500)
{
goto printing_result;
}
else
{
continue;
}
}
}
}
index_changing:
for (int l = 466; l > text_char_index + word_symbols; --l)
{
text[l] = text[l + 1];
}
goto insert;
printing_result:
printf("The result is--->>\n%s\n\n//////////////////////////////////////////END OF////////////////////////////////////////\n\n", text);
}
}
goto Start;
return 0;
}
If I enter the word was ( - it is word which i want to change in text) and than I enter the word detected (which has more symbols than first entered word - an it is the word which i want to insert in the text in return "was")
Console output is: There detected
And I can't use in this code method or something like that, I can only use if() and for loop.
Can anyone help me to understand how to do it?
First let's get the ground rules straight -- you are not allowed to use string functions/methods in this exercise, you have to write the code out explicity using primarily if statements and loops.
Rather than create a whole separate block of code to deal with the replacement word being larger than the original, just deal with it as part of the original replacement code -- as well as deal with the possibility that the replacement word is smaller. Both require shifting the original text one way or the other based on the difference between the original word and the replacement.
Here is a rework of your code that does the above and makes a number of style changes and bug fixes. It also makes it a pure 'C' program:
#include <stdio.h>
#include <stdbool.h>
int main()
{
printf("This program can change word or character combinations in text.\n\n");
char text[1024] =
"There was a grocery shop in a town. Plenty of mice lived in that grocery shop.\n"
"Food was in plenty for them. They also wasted the bread, biscuits and fruits\n"
"of the shop. The grocer got really worried. So, he thought I should buy a cat\n"
"and let it stay at the grocery. Only then I can save my things. He bought a\n"
"nice, big fat cat and let him stay there. The cat had a nice time hunting mice\n"
"and killing them. The mice could not move freely now. They were afraid that\n";
while (true) {
printf("%s\n", text);
int characters_in_text = 0;
for (int f = 0; text[f] != '\0'; f++) // not allowed to use strlen()
{
characters_in_text++;
}
printf("Text has %i characters.\n\n", characters_in_text);
char word[17];
printf("Which word would you like to change in text above?\n");
printf("(Maximum quantity of characters is %d)\n", (int) sizeof(word) - 2);
printf("Type word or some character(s)\n");
printf("--->> ");
(void) fgets(word, sizeof(word), stdin);
int a, word_characters = 0;
for (a = 0; word[a] != '\n'; a++)
{
word_characters++;
}
word[a] = '\0';
if (word_characters == 0)
{
break; // exit program
}
printf("Word which you have entered has %i characters.\n", word_characters);
int words_in_text = 0;
for (int i = 0; i < characters_in_text - word_characters; i++)
{
bool found = true;
for (int j = 0; j < word_characters; j++)
{
if (word[j] != text[i + j])
{
found = false;
break;
}
}
if (found)
{
char next_letter = text[i + word_characters];
if (next_letter == ' ' || next_letter == '.' || next_letter == ',' || next_letter == '\n' || next_letter == '\0')
{
words_in_text++;
}
}
}
printf("Found %i instance(s) of %s that are not part of another word.\n", words_in_text, word);
char replacement_word[17];
printf("Enter the word which you want to insert for first entered word.\n");
printf("(Maximum quantity of characters is %d)\n", (int) sizeof(replacement_word) - 2);
printf("Type word or some character(s)\n");
printf("--->> ");
(void) fgets(replacement_word, sizeof(replacement_word), stdin);
int replacement_word_characters = 0;
for (a = 0; replacement_word[a] != '\n'; a++)
{
replacement_word_characters++;
}
replacement_word[a] = '\0';
printf("The word which you have entered has %i characters.\n\n", replacement_word_characters);
int text_shift = replacement_word_characters - word_characters;
for (int i = 0; i < characters_in_text - word_characters; i++)
{
bool found = true;
for (int j = 0; j < word_characters; j++)
{
if (word[j] != text[i + j])
{
found = false;
break;
}
}
if (found)
{
char next_letter = text[i + word_characters];
if (next_letter == ' ' || next_letter == '.' || next_letter == ',' || next_letter == '\n' || next_letter == '\0')
{
if (text_shift > 0)
{
for (int k = characters_in_text; k > i + word_characters - 1; k--)
{
text[k + text_shift] = text[k];
}
}
else if (text_shift < 0)
{
for (int k = i + word_characters; k < characters_in_text + 1; k++)
{
text[k + text_shift] = text[k];
}
}
characters_in_text += text_shift;
for (int j = 0; j < replacement_word_characters; j++)
{
text[i + j] = replacement_word[j];
}
}
}
}
}
return 0;
}
You can see how complicated this code gets without library functions -- testing for the possible punctuation that follows a word would be a lot easier with functions like ispunct() in ctype.h
You also computed a number of useful values in your original code but failed to use them appropriately later on in the code.
Yet to do: you've a lot of error checks to add to this code -- what if the replacement makes the text larger than the array that contains it? You check that a word isn't contained in another by testing the character after the word but fail to test the character before the work, e.g. 'other' vs. 'another'.

Resources