If given the following char prose:
"Hope is the thing with feathers
That perches in the soul
And sings the tune without the words
And never stops at all”
How do I count the length of the string and number of spaces? Here is what I have thus far:
#include <stdio.h>
#include <ctype.h>
int count(char *string);
int main(void){
char prose[ ] =
"Hope is the thing with white feathers\n"
"That perches in the soul.\n"
"And sings the tne without the words\n"
"And never stops at all.";
printf("count of word : %d\n", count(&prose[0]));
return 0;
}
char *NextWordTop(char *string){
static char *p = NULL;
char *ret;
if(string)
p = string;
else if(!p)
return NULL;
while(isspace(*p))++p;
if(*p){
ret = p;
while(!isspace(*p))++p;
} else
ret = p = NULL;
return ret;
}
int count(char *str){
int c = 0;
char *p;
for(p=NextWordTop(str); p ; p=NextWordTop(NULL))
++c;
return c;
}
#include <stdio.h>
#include <ctype.h>
int main(void){
char prose[ ] =
"Hope is the thing with white feathers\n"
"That perches in the soul.\n"
"And sings the tne without the words\n"
"And never stops at all.";
int len, spc;
char *p = prose;
for(len=spc=0;*p;++p){
++len;
if(isspace(*p))//if(' ' == *p)
++spc;
}
printf("length : %d\t spaces : %d\n", len, spc);
//length : 123 spaces : 23
return 0;
}
Related
I'm trying to implement question 8.13 from C How to program, which is simply shifting left from the second char of the string and concat the first char of the string with "ay". For example:
jump -> umpjay the -> hetay and so on.
My try is here:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *appender(char s);
void shiftLeft(char [], int);
int main()
{
char s[100], *lastThree;
fgets(s, 100, stdin);
s[strcspn(s, "\n")] = 0;
char *tokenPtr = strtok(s, " ");
while(tokenPtr != NULL){
lastThree = appender(tokenPtr[0]);
//printf("lastThree : %s\n", lastThree); //for debugging
shiftLeft(tokenPtr, strlen(tokenPtr));
sprintf(tokenPtr, "%s%s ", tokenPtr, lastThree); // concatenation
printf("tokenptr:%s ", tokenPtr);
tokenPtr = strtok(NULL, " ");
}
return 0;
}
char *appender(char s){
char *returned = (char*)malloc(sizeof(char)*4); // allocation
snprintf(returned, sizeof(returned), "%c%s",s,"ay"); // append ay
return returned;
}
void shiftLeft(char s[], int len){
int i;
for(i=0;i<len-1;i++){
s[i]=s[i+1];
}
s[i] = '\0';
}
But code works wrong. It evaluates tokenPtr as yaay even if the input is only a word.
I would like to read input char by char and save it as a word into char* array. I don't know how long the input will be, so i want to alloc the memmory dynamicaly. The program ends,when the char is whitespace. How can i do this using realloc?
There is my code:
#include <stdio.h>
int main(void) {
char *word=malloc(1*sizeof(char));
char c;
int numOfChars=0;
c=getchar();
word[0]=c;
numOfChars++;
while((c=getchar())!=' '){
numOfChars++;
realloc(word,numOfChars);
word[numofChars-1]=c;
}
printf("%s", word);
return 0;
}
Example input:Word
Example output:Word
The program can look the following way. Take into account that the input is buffered and filled until a new line character is entered that is also a white space character. And the result word must be zero terminated if you are going to use format specifier %s to output it.
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main( void )
{
int c;
size_t n;
char *word;
char *tmp;
n = 0;
word = malloc( n + 1 );
word[n++] = '\0';
printf( "Enter a word: " );
while ( ( c = getchar() ) != EOF && !isspace( c ) && ( tmp = realloc( word, n + 1 ) ) != NULL )
{
word = tmp;
word[n-1] = c;
word[n++] = '\0';
}
printf( "You've entered \"%s\"\n", word );
free( word );
}
The program output might look like
Enter a word: Hello
You've entered "Hello"
In order to explain what I had in mind, i quickly set up this little programm to explain how to use an exponential growth :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INITIAL_CAPACITY 100
#define GROW_FACTOR 1.5
struct string_buffer {
size_t capacity;
size_t length;
char *buffer;
};
typedef struct string_buffer string_buffer_t;
string_buffer_t *sb_init(void);
static void sb_grow(string_buffer_t *sb);
void sb_shrink(string_buffer_t *sb);
char *sb_release(string_buffer_t *sb);
void sb_append_char(string_buffer_t *sb, char c);
char *sb_peek_string(string_buffer_t *sb);
int main(void)
{
string_buffer_t *sb=sb_init();
int c;
while ( (c=getchar())!=' ' && c!='\n' && c!=EOF )
sb_append_char(sb, c);
char *string=sb_release(sb);
printf("string : \"%s\"\nlength : %zu\n", string, strlen(string));
free(string);
return 0;
}
string_buffer_t *sb_init(void)
{
string_buffer_t *new=malloc(sizeof *new);
if (new==NULL) exit(EXIT_FAILURE);
new->capacity=INITIAL_CAPACITY;
new->length=1;
new->buffer=malloc(INITIAL_CAPACITY);
if (new->buffer==NULL) exit(EXIT_FAILURE);
new->buffer[0]=0;
return new;
}
static void sb_grow(string_buffer_t *sb)
{
char *new=realloc(sb->buffer, (size_t) (GROW_FACTOR*sb->capacity));
if (new==NULL) exit(EXIT_FAILURE);
sb->capacity=(size_t) (GROW_FACTOR*sb->capacity);
sb->buffer=new;
}
void sb_shrink(string_buffer_t *sb)
{
char *new=realloc(sb->buffer, sb->length);
if (new==NULL) exit(EXIT_FAILURE);
sb->buffer=new;
}
char *sb_release(string_buffer_t *sb)
{
sb_shrink(sb);
char *string=sb->buffer;
free(sb);
return string;
}
void sb_append_char(string_buffer_t *sb, char c)
{
if (sb->capacity==sb->length) sb_grow(sb);
sb->buffer[sb->length-1]=c;
sb->buffer[sb->length]=0;
sb->length=sb->length+1;
}
This will do
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *ptr;
char *word=malloc(1*sizeof *word);
char c;
int numofChars=0;
printf("Enter string terminated by a space :");
c=getchar();
word[0]=c;
numofChars++;
while((c=getchar())!=' '){
numofChars++;
ptr=realloc(word,numofChars*sizeof *ptr);
if(ptr!=NULL)
{
word=ptr;
word[numofChars-1]=c;
}
}
/* You need to append a null character to make it a valid string */
numofChars++;
ptr=realloc(word,numofChars*sizeof *ptr);
if(ptr!=NULL)
{
word=ptr;
word[numofChars-1]='\0';
}
printf("Word : %s\n", word);
free(word); // Freeing word/
return 0;
}
Well, you may write a function to replace
numofChars++;
ptr=realloc(word,numofChars*sizeof *ptr);
if(ptr!=NULL)
{
word=ptr;
word[numofChars-1]='\0';
}
Note:
It is not suggested that you do
word=realloc(word,numOfChars*sizeof(char));
because in case realloc fails, you have memory leak. So I used ptr here.
I have a string in my program where in which it need to be altered with another string value before a "/".
Source String : qos-tree/output_rate
Target String : qos-tree-2/output_rate
#include <stdio.h>
#include <string.h>
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main(void)
{
char str[256] = "qos-tree/output_rate";
char c = "a";
append(str, c);
printf("%s\n", str);
return 0;
}
This is what i have done so far,I think the logic is wrong here.Can anyone guide me to correct it?
Once the execution is completed the source string should have a "-2" before the "/"
void insert_before_ch(char *s, const char *ins, char c){
char *p = strchr(s, c);
if(p){
size_t len = strlen(ins);
memmove(p + len, p, strlen(p)+1);
memcpy(p, ins, len);
}
}
int main(void){
char str[256] = "qos-tree/output_rate";
insert_before_ch(str, "-2", '/');
printf("%s\n", str);
return 0;
}
In your attempt, you don't look for a slash and I do not see any "-2" anywhere.
Try this instead:
#include <stdio.h>
#include <string.h>
void append(char* s, char del, char* substring) {
char origin[256];
strcpy(origin, s);
int i = 0, j = 0, z = 0;
for(; origin[i]; ++i) {
if(origin[i] != del) {
s[j++] = origin[i];
} else {
for(; substring[z]; ++z) {
s[j++] = substring[z];
}
s[j++] = origin[i];
}
}
s[j] = '\0';
}
int main(void) {
char str[256] = "qos-tree/output_rate";
char del = '/';
char* substring = "-2";
append(str, del, substring);
printf("%s\n", str);
return 0;
}
The logic is that inside the function we use origin array to remember the actual contents of the array and then we copy from origin to s (which is the actual array of main()). If we find our delimiter del, then we copy the substring in that position and continuing with copying.
Note that the length of the array should be enough to store the resulted string. In this case, it is.
I think you should make your function work with dynamic allocation, because inserting characters into the string will make the resulting string larger, so this is my suggestion
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void insert(char **str, char chr, unsigned int position)
{
int length;
char *ptr;
if (str == NULL)
return;
length = strlen(*str);
if (position >= length)
return;
ptr = realloc(*str, 2 + length);
if (ptr == NULL)
return;
*str = ptr;
memmove(ptr + position + 1, ptr + position, length - position + 1);
ptr[position] = chr;
}
int main(void)
{
const char *source = "qos-tree/output_rate";
size_t length = strlen(source);
char *str = malloc(1 + length);
if (str == NULL)
return -1;
strcpy(str, source);
insert(&str, '-', 8);
insert(&str, '2', 9);
printf("%s\n", str);
free(str);
return 0;
}
first of all thist char c = "a" should be replace with this char c = 'a'; because c is a character not a string
as for your problem I didn't realy see the relation between what your code is doing with what you said you wanted to do , but here a piece of code to achieve what , I think , you want to do :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void append(char* str , char c)
{
char firststr[60];
char therest[30];
strcpy(firststr , strtok(str , "/"));
strcpy(therest , strtok(NULL , "/"));
strcat(firststr , &c);
strcat(firststr , "/");
strcat(firststr , therest);
strcpy(str , firststr);
}
int main(void)
{
char str[60] = "qos-tree/output_rate";
char c = '2';
append(str , c);
printf("%s\n" , str);
}
there you go I think this is what you wanted to do you can modify the array sizes to fit your needs
I have written the following code to reverse a String. But it is giving some error. It get stuck after calling the reverseStr() function. I am unable to find the bug. Can someone help me?
#include <stdio.h>
#include <stdlib.h>
char * reverseStr(char *str){
int i,len = 0;
while(str[len]!=NULL){
len++;
}
len-=1;char temp;
for(i=0;i<len/2;i++){
//printf("%d %d %s\n",i,len,str);
temp = str[len-i];
str[len-i]=str[i];
str[i]=temp;
//printf("%d %d %s\n",i,len,str);
}
return str;
}
int main(void) {
char *str = "abcdefg";
printf("Original :: %s\n",str);
str = reverseStr(str);
printf("Reversed :: %s",str);
return 0;
}
char *str = "abcdefg";
will place string literal "abcdefg" in the read-only section of the memory and making str to point to that, any writing operation on this memory illegal and hence the runtime error.
Use char str[] = "abcdefg" ; and simply reverseStr(str);
Now you can't do str = reverseStr(str) ; here since types are different, you can store the result in another char pointer though.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverseStr(char *str){
int i,len;
len = strlen(str);
char temp1,temp2;
int j = len - 1;
for(i=0;i<j/2 + j%2;i++){
printf("%d %d %s\n",i,j,str);
temp1 = str[j-i];
temp2 = str[i];
str[i]=temp1;
str[j-i]=temp2;
printf("%d %d %s\n",i,j,str);
}
return;
}
int main(void) {
char str[10];
strcpy(str,"abcdefgh");
printf("Original :: %s\n",str);
reverseStr(str);
printf("Reversed :: %s",str);
return 0;
}
Here is a program to accept a:
Sentence from a user.
Word from a user.
How do I find the position of the word entered in the sentence?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char sntnc[50], word[50], *ptr[50];
int pos;
puts("\nEnter a sentence");
gets(sntnc);
fflush(stdin);
puts("\nEnter a word");
gets(word);
fflush(stdin);
ptr=strstr(sntnc,word);
//how do I find out at what position the word occurs in the sentence?
//Following is the required output
printf("The word starts at position #%d", pos);
return 0;
}
The ptr pointer will point to the beginning of word, so you can just subtract the location of the sentence pointer, sntnc, from it:
pos = ptr - sntnc;
Just for reference:
char saux[] = "this is a string, try to search_this here";
int dlenstr = strlen(saux);
if (dlenstr > 0)
{
char *pfound = strstr(saux, "search_this"); //pointer to the first character found 's' in the string saux
if (pfound != NULL)
{
int dposfound = int (pfound - saux); //saux is already pointing to the first string character 't'.
}
}
The return of strstr() is a pointer to the first occurence of your "word", so
pos=ptr-sntc;
This only works because sntc and ptr are pointers to the same string. To clarify when I say occurence it is the position of the first matching char when the matching string is found within your target string.
You can use this simple strpos modification
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int strpos(char *haystack, char *needle, int offset);
int main()
{
char *p = "Hello there all y'al, hope that you are all well";
int pos = strpos(p, "all", 0);
printf("First all at : %d\n", pos);
pos = strpos(p, "all", 10);
printf("Second all at : %d\n", pos);
}
int strpos(char *hay, char *needle, int offset)
{
char haystack[strlen(hay)];
strncpy(haystack, hay+offset, strlen(hay)-offset);
char *p = strstr(haystack, needle);
if (p)
return p - haystack+offset;
return -1;
}
For some reasons I was having trouble with strstr(), and I also wanted index.
I made this function to find the position of substring inside a bigger string (if exists) otherwise return -1.
int isSubstring(char * haystack, char * needle) {
int i = 0;
int d = 0;
if (strlen(haystack) >= strlen(needle)) {
for (i = strlen(haystack) - strlen(needle); i >= 0; i--) {
int found = 1; //assume we found (wanted to use boolean)
for (d = 0; d < strlen(needle); d++) {
if (haystack[i + d] != needle[d]) {
found = 0;
break;
}
}
if (found == 1) {
return i;
}
}
return -1;
} else {
//fprintf(stdout, "haystack smaller\n");
}
}
My comment to the ORIGINAL post in this thread:
This declaration is INCORRECT:
char sntnc[50], word[50], *ptr[50];
C code would not even compile : it will fail on this line:
ptr = strstr(sntnc,word);
So the line shall be changed to :
char sntnc[50], word[50], *ptr;
And you do NOT need memeory allocated to 'ptr string'. You just need a pointer to char.