I am reading a .txt file which contains data in a random form i.e. it contains integers and strings mixed in it.
Sample .txt file:
this is a 22 string 33 sorry222 stack33ing
still yysi288 2nd line
I want to read the file and differentiate all valid string i.e. which do not contain integers concatinated with them. And store those strings in an array.
Any leads on how to differentiate?
You can use #include <ctype.h> for that purpose.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int checkString( const char s[] ) {
unsigned char c;
while ( ( c = *s ) && ( isalpha( c ) || isblank( c ) ) ) ++s;
return *s == '\0';
}
void printNonNumericWords(char str[]) {
int init_size = strlen(str);
char delim[] = " ";
char *ptr = strtok(str, delim);
while(ptr != NULL)
{
if (checkString(ptr))
printf("'%s'\n", ptr);
ptr = strtok(NULL, delim);
}
printf("\n");
}
Call function like this.
printNonNumericWords(this is a 22 string 33 sorry222 stack33ing");
First: I can´t write the programm for you. It is your task to do and beside this i can´t even change things on your code or at least suggest to alter, because you are not providing any code. I can give you only a dusty leading algorithm for this case:
All the words you might see, are not valid strings in the file. It is only one string containing white space characters between each sequence of characters which appear for you as one word or separated string, but it doesn´t.
You have to get the whole string from the file first and store it into an char array, lets name it source, using fgets():
#include <stdio.h>
FILE *input;
char source[200];
input = fopen("text.txt","r");
fgets(source, 200, input);
After that you need to make those "words" separated strings by transport each of the characters of the source string, one after another, to other char arrays and quit writing the characters to them as soon as the space character or the NUL-byte after the last word is provided in the source string. Don´t forget to make a Nul-Byte (\n) terminating each string.
Thereafter you check each, now valid and separated string, if it either is a string that contains numbers or a string without any number.
Related
I need to try and fix sentences from an input in c, so I tried separating tokens and making new strings and then I wanted to access the first char of each string and make it a capital letter.
Now I am having trouble understanding how to access only one char of each new string, like trying to access only 'e' in hello which is in str1[0] second char.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char str1[601], * str2[601];
int i = 0, j = 0;
printf_s("*************** Welcome to the text cleaner ***************\n\n");
printf_s("Please enter text:\n");
gets_s(str1, sizeof(str1));
char* sentence=NULL,*next_sentence=NULL;
sentence = strtok_s(str1,".",&next_sentence);
while (sentence != NULL)
{
printf(" %s\n", sentence);
str2[i++] = sentence;
sentence = strtok_s(NULL, ".", &next_sentence);
}
str2[i++] = '\0';
printf_s("%s", str2[1]);
}
Code and content of variables in debugger
Here is my take on what you are trying to do. I'm showing the code and the results. I have simplified your effort since you are mixing printf and printf_s. You use the _s variant for buffer overflow control. That does not seem to be your concern while simply learning about arrays.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main() {
char str1[601]; // This is an array of chars.
// If storing a string, final elem is 0x0
char *str2[601]; // This is a pointer to an array of chars.
//
int i = 0;
int j = 0;
// I removed your _s variants of standard libraries. Let's keep
// things simple.
printf("*************** Welcome to the text cleaner ***************\n\n");
printf("Please enter text:\n");
// ditto for gets to fgets
//
// Excerpt rom the manpage
//
// char *fgets(char *s, int size, FILE *stream);
//
// fgets() reads in at most one less than size characters from
// stream and stores them into the buffer pointed to by s.
// Reading stops after an EOF or a newline. 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.
//
// fgets() returns s on success, and NULL on error or when end of
// file occurs while no characters have been read.
//str1 = fgets(str1, sizeof(str1), stdin);
// I would do a null check here.
if (NULL == fgets(str1, sizeof(str1), stdin)) {
return; // graceful exit
}
// Notice on the bracket print of your text, the closing >
// is shown on the next line. This is because its capturing the
// newline/carriage return character.
printf("You entered %d chars and the text was:\n<%s>\n", strlen(str1), str1);
// These are for your strtok operation
// I would call them tokens or words, but
// whatever.
char *sentence=NULL;
char *next_sentence=NULL;
// wants to parse a string
// Excerpt from manpage
//
// char *strtok(char *str, const char *delim);
// Ahh, now I see why you name is sentence. You
// are looking for periods to separage sentences.
printf("Lets use strtok\n");
sentence = strtok(str1, ".");
while (sentence != NULL) {
printf("A sentence is:\n %s\n", sentence);
str2[i++] = sentence;
sentence = strtok(NULL, ".");
}
// So now, your individual sentences are stored
// in the array str2.
// str2[0] is the first sentence.
// str2[1] is the next sentence.
//
// To access the characters, specify a sentence and
// then specify the character.
//
// You can do the math, but do a man ascii, look at
// difference in lowercase a and uppercase A in terms
// of ascii. If its not captializ3ed already, simply
// add that offset or error out if not in set a-z.
//
// Here I will just make the first letter of the second
// sentence to be J.
str2[1][0] = 'J';
// Note, since you are going to have in the 'space'
// since you are delimitting on '.', It will have the
// effect of replacing 'space' with 'J'.
printf("Sentence two is: \n%s\n", str2[1]);
}
Here is the code in action.
*************** Welcome to the text cleaner ***************
Please enter text:
John was here. and here.
You entered 25 chars and the text was:
<John was here. and here.
>
Lets use strtok
A sentence is:
John was here
A sentence is:
and here
A sentence is:
Sentence two is:
Jand here
I hope that helps. TLDR use str2[x][y] to access a string x at character y.
I am trying to make a simple game similar to the now popular game Wordle, but I am having trouble comparing a user inputted string to that of a pre-existing string. I want to be able to compare the strings as a whole as well as each individual letter in the input and the answer. Here is the code i am working with:
#include <stdio.h>
#include <string.h>
int main()
{
char guess[5];
char answer[5] = "money";
printf("what is your first guess? ");
scanf("%s",&guess);
if (strcmp(guess,answer) == 0){
printf("\nyour guess was correct");
}
else{
printf("Your guess was incorrect");
}
return 0;
}
The user may input significantly more characters than 5-1=4.
Also, use fgets(), not scanf().
char guess[100];
fgets( guess, sizeof(guess), stdin );
Don’t forget to remove the Enter key from the user’s input:
char * p = strchr( guess, '\n' );
if (p) *p = '\0';
When storing constant character arrays, declare it with a pointer:
const char * answer = "money";
If you have a fixed list of answers, use the const array.
When storing mutable character arrays, declare it either with a large space (for future use):
char answer[100] = "money";
or let the compiler declare the exact number of elements you need:
char answer[] = "money";
I presume you will want to randomly select an answer for the user to guess at some point, so the 100-element array is a better choice. Use this if you wish to have a file of answers to use at some point.
You will probably want to normalize the user’s input in some way as well. For example, if all your answers are lowercase, you should transform user input to lowercase before comparing.
#include <ctype.h>
char * stolower( char * s )
{
for (char * p = s; *p; ++p)
*p = tolower( *p );
return s;
}
if (strcmp(tolower(guess),answer) == 0){
C strings like "money" contains 6 chars, with an extra '\0' to mark the end of a string. Which means, when stored with a char array, you'll always need an extra space for '\0' in order to use the char array as a string.
For example, strcmp for char str[10] = "aaa\0bbb" and char[4] = "aaa" will be 0 (equal), because the program will see '\0' as the end of a string, ignoring the extra chars. (btw, the way "aaa" stored in the char array is like this: ['a', 'a', 'a', '\0'])
I want to parse a string into a note and octave. For example if the user inputs "A#4", (A#)-note that will be stored in (char n) and (4)- octave that will be stored in (char o). Why am I getting blanked line instead of 4 as output after A#?
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main()
{
string src = get_string();
char *n;
char *o;
char *note = "ABCDEFG#b";
char *octave = "12345678";
o = strtok(src, note);
n = strtok(src, octave);
printf("%s\n", n);
printf("%s\n", o);
}
Output:
A#
Can you please point to error and suggest a solution?
strtok is not the function you want to use in this instance.
When you call it, it alters the string, replacing the character that matches the deliminator with a NUL so you'll lose the character you're looking for as the note. The second time you call it with src, the string will appear empty and it won't find anything - you're meant to call it on subsequent times with the first parameter set to NULL so that it knows you're searching for the next token in the same string.
You might want to use strspn which counts the number of characters that match your set (ie note) or strpbrk that finds the first character that matches.
Or you could traverse the string yourself and use strchr like this
char *pos;
for(pos=src;*pos!='\0';pos++)
{
if(strchr(note,*pos))
{
// *pos is a note character
}
}
Whatever you use, you'll need to build a new string based on your results as the original string won't have space to put NUL terminators inside to separate out the two parts you're looking for.
I am very new in C, I have little idea about sprintf but I can't fulfill my requirement.
I have a char * variable which contains string like below :
date=2013-12-09 time=07:31:10 d_id=device1 logid=01 user=user1 lip=1.1.1.1 mac=00:11:22:33:44:55 cip=2.2.2.2 dip=3.3.3.3 proto=AA sport=22 dport=11 in_1=eth1 out_1=
I want an output as
2013-12-09#07:31:10#device1#01#user1#1.1.1.1#00:11:22:33:44:55#2.2.2.2#3.3.3.3#AA#22#11#eth1##
if some value is null after = it should print ## in sequence.
I am not going to give you exact code but I will give you some links that will help you.
strchr :: You can use this find the position of '=' in the string.
Now, copy the string after the position of '=' till you find a 'space'.
Whenever you will find a 'space', write a '#' in the buffer.
Keep doing this, till you encounter a '\0'. Write '##' to buffer when you have encountered '\0'
Append that with a '\0'.
Ex:: C function strchr - How to calculate the position of the character?
example by use strtok, strchr, sprintf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
const char *data = "date=2013-12-09 time=07:31:10 d_id=device1 logid=01 user=user1 lip=1.1.1.1 mac=00:11:22:33:44:55 cip=2.2.2.2 dip=3.3.3.3 proto=AA sport=22 dport=11 in_1=eth1 out_1=";
char *work = strdup(data);//make copy for work
char *output = strdup(data);//allocate for output
char *assignment; //tokenize to aaa=vvv
size_t o_count = 0;//output number of character count
for(assignment=strtok(work, " "); assignment ;assignment=strtok(NULL, " ")){
o_count += sprintf(output + o_count, "%s#", strchr(assignment, '=')+1);
}
printf("%s", output);
free(work);
free(output);
return 0;
}
Just looking to be pointed in the right direction:
Have standard input to a C program, I've taken each line in at a time and storing in a char[].
Now that I have the char[], how do I take the last word (just assuming separated by a space) and then convert to lowercase?
I've tried this but it just hangs the program:
while (sscanf(line, "%s", word) == 1)
printf("%s\n", word);
Taken what was suggested and came up with this, is there a more efficient way of doing this?
char* last = strrchr(line, ' ')+1;
while (*last != '\0'){
*last = tolower(*last);
putchar((int)*last);
last++;
}
If I had to do this, I'd probably start with strrchr. That should get you the beginning of the last word. From there it's a simple matter of walking through characters and converting to lower case. Oh, there is the minor detail that you'd have to delete any trailing space characters first.
The issue with your code is that it will repeatedly read the first word of the sentence into word. It will not move to the next word each time you call it. So if you have this as your code:
char * line = "this is a line of text";
Then every single time sscanf is called, it will load "this" into word. And since it read 1 word each time, sscanf will always return 1.
This will help:
char dest[10], source [] = "blah blah blah!" ;
int sum = 0 , index =0 ;
while(sscanf(source+(sum+=index),"%s%n",dest,&index)!=-1);
printf("%s\n",dest) ;
'strtok' will split the input string based on certain delimitors, in your case the delimitor would be a space, thus it will return an array of "words" and you would simply take the last one.
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
One could illustrate many different methods of performing this operation and then determine which one contained the best performance and useability characteristics, or the advantages and disadvantages of each, I simply wanted to illustrate what I mentioned above with a code snippet.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
int main()
{
char line[] = "This is a sentence with a last WoRd ";
char *lastWord = NULL;
char *token = strtok(line, " ");
while (token != NULL)
{
lastWord = token;
token = strtok(NULL, " ");
}
while (*lastWord)
{
printf("%c", tolower(*lastWord++));
}
_getch();
}