How to add chars to an empty string? - c

I'm trying to write a C program that only prints the last occurrence of repeating letters of a string. I have that part done but I want to store all those chars in a string. What I have so far is:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
bool isLast(char *arg1, char ch, int p) {
p++;
while (arg1[p] != '\0') {
if ((arg1[p]) == ch) {
return false;
}
p++;
}
return true;
}
int main() {
char *word = "kaax";
char *vals = "1235";
char *result = "";
for (int i = 0; word[i] != '\0'; i++) {
if (isLast(word, word[i], i)) {
result += vals[i];
}
}
printf("%s", result);
}
I want:
printf("%s",result);
to print:
fxkav
Since that is the logical result of my program and what the output should be.

How to phrase it ... Not at all.
Your "empty string" is a string literal of size 1 (containing only '\0'. It cannot be changed and even lesss extended.
If you need to manipulate "strings" (which in C is not really an existing concept) you need to represent them as sequences of characters, which are stored in a data structure which allows to change the contained characters and, in your case, also has space for more characters.
In cases where you can determine a maximum size (MAXSIZE) you could define an array of characters of that size like this
char SizedCharArray[MAXSIZE];

Related

Using strncmp by checking only a variable single element of a char array

I am trying to write a code which compares the letters of a char array one by one against a determined letter (letter 'l'). When this is the case in the output string, there are two 'l's. For instance, "lily" should become "llilly". I fail to see how to implement this in C because something like this :
strncmp (word[indx],'l',1) //where indx is an iterator of the char array 'word'
is not valid because the first argument should be 'word' but then there is no way to iterate through 'word'.
And of course if we wrote:
strncmp (word,'l',indx)
The problem is that now we are checking more than one letter at a time after indx becomes equal or larger than 2 and what we really want is to check one character at a time.
This is my code so far:
#include <stdio.h>
#include <string.h>
const char* ModifyString (char word []);
int main(){
char word[6]="Hello";
printf("The result is %s \n", ModifyString(word));
return 0;
}
const char* ModifyString (char word []) {
size_t lengthString=strlen(word);
char modifiedString[lengthString*2+1]; //to fit the nul terminator and all the 'l's in case the word only contained 'l's.
int indxModWord=0;
for (int indx=0; indx<lengthString;indx++) {
//This line does not express what I want to do:
if (strncmp(word,"l",indx)==0) {
modifiedString[indxModWord]=word[indx];
indxModWord++;
}
// if 'l' in word make it appear twice in the output string
else {
modifiedString[indxModWord]='l';
indxModWord++;
modifiedString[indxModWord]='l';
indxModWord++;
}
}
printf("%s", modifiedString);
}
Does anyone has any idea how I should do this in C?
Simply compare the characters as in other answers.
But of course, you can use strncmp to compare the chars if you wish.
strncmp (&word[indx],(char []){'l'},1);
or you can write the function:
int compareCharsUsingStrncmp(const char a, const char b)
{
return strncmp((char[]){a}, (char[]){b}, 1);
}
or
int compareCharsUsingStrncmp(const char a, const char b)
{
return strncmp(&a, &b, 1);
}
Smart compilers will not even call the strncmp :)
compareCharsUsingStrncmp:
movzx eax, dil
movzx esi, sil
sub eax, esi
ret
While traversing the given string, keep a check to see if the current character of the string is you target character (in your case 'l').
Code:
const char* ModifyString (char word [])
{
size_t lengthString=strlen(word);
char modifiedString[lengthString*2+1]; //to fit the nul terminator and all the 'l's in case the word only contained 'l's.
int indxModWord=0;
char targetCharacter = 'l';
for (int indx=0; indx<lengthString; indx++)
{
if (word[indx] != targetCharacter)
{
modifiedString[indxModWord] = word[indx];
indxModWord++;
}
else
{
modifiedString[indxModWord] = targetCharacter;
indxModWord++;
modifiedString[indxModWord] = targetCharacter;
indxModWord++;
}
}
modifiedString[indxModWord] = '\0';
printf("%s", modifiedString);
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *ModifyString (char* word) {
size_t lengthString = strlen(word);
//to fit the nul terminator and all the 'l's in case the word only contained 'l's.
char *modifiedString;
modifiedString=(char*)malloc(lengthString*2+1);
size_t indxModWord=0;
for (int indx=0; indx<lengthString;indx++) {
//This line does not express what I want to do:
if (word[indx] != 'l'){
modifiedString[indxModWord]=word[indx];
indxModWord++;
}
// if 'l' in word make it appear twice in the output string
else {
modifiedString[indxModWord]='l';
indxModWord++;
modifiedString[indxModWord]='l';
indxModWord++;
}
}
return (char *)modifiedString;
}
int main(){
char word[]="Hello";
char *result ;
result = ModifyString(word);
printf("The result is %s \n",result);
return 0;
}
Please check if this is what you were looking for.

Writing a C program that removes every occurrence of a char except the last one

Im trying to write a C program that removes all occurrences of repeating chars in a string except the last occurrence.For example if I had the string
char word[]="Hihxiivaeiavigru";
output should be:
printf("%s",word);
hxeavigru
What I have so far:
#include <stdio.h>
#include <string.h>
int main()
{
char word[]="Hihxiiveiaigru";
for (int i=0;i<strlen(word);i++){
if (word[i+1]==word[i]);
memmove(&word[i], &word[i + 1], strlen(word) - i);
}
printf("%s",word);
return 0;
}
I am not sure what I am doing wrong.
With short strings, any algorithm will do. OP's attempt is O(n*n) (as well as other working answers and #David C. Rankin that identified OP's short-comings.)
But what if the string was thousands, millions in length?
Consider the following algorithm: #paulsm4
Form a `bool` array used[CHAR_MAX - CHAR_MIN + 1] and set each false.
i,unique = n - 1;
From the end of the string (n-1 to 0) to the front:
if (character never seen yet) { // used[] look-up
array[unique] = array[i];
unique--;
}
Mark used[array[i]] as true (index from CHAR_MIN)
i--;
Shift the string "to the left" (unique - i) places
Solution is O(n)
Coding goal is too fun to just post a fully coded answer.
I would first write a function to determine if a char ch at a given position i is the last occurence of ch given a char *. Like,
bool isLast(char *word, char ch, int p) {
p++;
ch = tolower(ch);
while (word[p] != '\0') {
if (tolower(word[p]) == ch) {
return false;
}
p++;
}
return true;
}
Then you can use that to iteratively emit your desired characters like
int main() {
char *word = "Hihxiivaeiavigru";
for (int i = 0; word[i] != '\0'; i++) {
if (isLast(word, word[i], i)) {
putchar(word[i]);
}
}
putchar('\n');
}
And (for completeness) I used
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
Outputs (as requested)
hxeavigru
Additional areas where you are currently hurting yourself.
Your for loop must NOT increment the index, e.g. for (int i=0; word[i];). This is because when you memmove() by 1, you have just incremented the indexes. That also means the value to save for last is now i - 1.
there should only be one call to strlen() in the program. You can simply subtract one from length each time memmove() is called.
only increment your loop counter variable when memmove() is not called.
Additionally, avoid hardcoding strings. You shouldn't have to recompile your code just to test the results of "Hihxiivaeiaigrui" instead of "Hihxiivaeiaigru". You shouldn't have to recompile just to remove all but the last 'a' instead of the 'i'. Either pass the string and character to find as arguments to your program (that's what int argc, char **argv are for), or prompt the user for input.
Putting it altogether you could do (presuming word is 1023 characters or less):
#include <stdio.h>
#include <string.h>
#define MAXC 1024
int main (int argc, char **argv) {
char word[MAXC]; /* storage for word */
strcpy (word, argc > 1 ? argv[1] : "Hihxiivaeiaigru"); /* copy to word */
int find = argc > 2 ? *argv[2] : 'i', /* character to find */
last = -1; /* last index where find found */
size_t len = strlen (word); /* only compute strlen once */
printf ("%s (removing all but last %c)\n", word, find);
for (int i=0; word[i];) { /* loop over each char -- do NOT increment */
if (word[i] == find) { /* is this my character to find? */
if (last != -1) { /* if last is set */
/* overwrite last with rest of word */
memmove (&word[last], &word[last + 1], (int)len - last);
last = i - 1; /* last now i - 1 (we just moved it) */
len = len - 1;
}
else { /* last not set */
last = i; /* set it */
i++; /* increment loop counter */
}
}
else /* all other chars */
i++; /* just increment loop counter */
}
puts (word); /* output result -- no need for printf (no coversions) */
}
Example Use/Output
$ ./bin/rm_all_but_last_occurrence
Hihxiivaeiaigru (removing all but last i)
Hhxvaeaigru
What if you want to use "Hihxiivaeiaigrui"? Just pass it as the 1st argument:
$ ./bin/rm_all_but_last_occurrence Hihxiivaeiaigrui
Hihxiivaeiaigrui (removing all but last i)
Hhxvaeagrui
What if you want to use "Hihxiivaeiaigrui" and remove duplicate 'a' characters? Just pass the string to search as the 1st argument and the character to find as the second:
$ ./bin/rm_all_but_last_occurrence Hihxiivaeiaigrui a
Hihxiivaeiaigrui (removing all but last a)
Hihxiiveiaigrui
Nothing removed if only one of the characters:
$ ./bin/rm_all_but_last_occurrence Hihxiivaeiaigrui H
Hihxiivaeiaigrui (removing all but last H)
Hihxiivaeiaigrui
Let me know if you have further questions.
Im trying to write a C program that removes all occurrences of repeating chars in a string except the last occurrence.
Process the string (or word) from last character and move towards the first character of string (or word). Now, think of it as a problem where you have to remove all occurrence of a character from string and except the first occurrence. Since, we are processing the string from last character to first character, so, we have to move the characters, which are remain after removing duplicates, to the start of string once you have processed whole string and, if, there were duplicate characters found in the string. The complexity of this algorithm is O(n).
Implementation:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define INDX(x) (tolower(x) - 'a')
void remove_dups_except_last (char str[]) {
int map[26] = {0}; /* to keep track of a character processed */
size_t len = strlen (str);
char *p = str + len; /* pointer pointing to null character of input string */
size_t i = 0;
for (i = len; i != 0; --i) {
if (map[INDX(str[i - 1])] == 0) {
map[INDX(str[i - 1])] = 1;
*--p = str[i - 1];
}
}
/* if there were duplicates characters then only copy
*/
if (p != str) {
for (i = 0; *p; ++i) {
str[i] = *p++;
}
str[i] = '\0';
}
}
int main(int argc, char* argv[])
{
if (argc != 2) {
printf ("Invalid number of arguments\n");
return -1;
}
char str[1024] = {0};
/* Assumption: the input string/word will contain characters A-Z and a-z
* only and size of input will not be more than 1023.
*
* Leaving it up to you to check the valid characters in input string/word
*/
strcpy (str, argv[1]);
printf ("Original string : %s\n", str);
remove_dups_except_last (str);
printf ("Removed duplicated characters except the last one, modified string : %s\n", str);
return 0;
}
Testcases output:
# ./a.out Hihxiivaeiavigru
Original string : Hihxiivaeiavigru
Removed duplicated characters except the last one, modified string : hxeavigru
# ./a.out aa
Original string : aa
Removed duplicated characters except the last one, modified string : a
# ./a.out a
Original string : a
Removed duplicated characters except the last one, modified string : a
# ./a.out TtYyuU
Original string : TtYyuU
Removed duplicated characters except the last one, modified string : tyU
You can re-iterate to get each characters of your string, then if it is not "i" and not the last occurrence of the i, copy to a new string.
#include <stdio.h>
#include <string.h>
int main() {
char word[]="Hihxiiveiaigru";
char newword[10000];
char* ptr = strrchr(word, 'i');
int index=0;
int index2=0;
while (index < strlen(word)) {
if (word[index]!='i' || index ==(ptr - word)) {
newword[index2]=word[index];
index2++;
}
index++;
}
printf("%s",newword);
return 0;
}

Convert ASCII code to string in C

I am trying to create a char array based on a single ASCII code. The folowing code does not compile correctly, even though "num" is cast to a char:
//Returns the ASCII counterpart of a number, such as 41 = A, 42 = B, 43 = C, etc.
char numToASCII(int num) {
char[] string = {(char)num, "\0"};
return string;
}
For the task that I am given, it is very important that "string" be a character array/string and not a single char. Any help would be appreciated.
The array must be initialized to constant expressions and your function should return a pointer if you want to return an array.
If you just want to return a char, then use the following code instead:
char numToASCII(int num) {
return (char)num;
}
If you want to return a string which contains the character, then you should use the following code:
#include <stdlib.h>
char *numToASCII(int num) {
/*
* Use malloc to allocate an array in the heap, instead of using a
* local array. The memory space of local array will be freed after
* the invocation of numToASCII.
*/
char *string = malloc(2);
if (!string)
return 0;
string[0] = num;
string[1] = 0;
return string;
}
Use the free() function to free the space allocated by malloc().
Try this..
You want to find the character for the ASCII code,then try this code:
#include<stdio.h>
int main()
{
int num;
printf("\nEnter ASCII Code Number:\t");
scanf("%d", &num);
printf("\nASCII Value of %d: \t%c", num, num);
printf("\n");
return 0;
}
In this code it will get the ASCII code from the user and it will print the character for the ASCII code as default.
Not sure if this helps but pulling text from a file comes back as ascii, I needed a string and got around it by checking the string length, sorry for extra steps as I too am very new.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char firstbuff[yourchoice];
char secondbuff[yourchoice];
char sentence[yourchoice];
int stringlenght;
fp = fopen("test.txt", "r");
//Here add a means of counting the lines in the file as linecount
for(int j = 0; j < linecount; j++)
{
fgets(firstbuff; 1000; fp);
//get string length and use for loop to individually ascii copy as characters into array
stringlength = strlen(firstbuff);
for(int i = 0; i < stringlength; i++)
{
secondbuff[i] = (char)firstbuff[i];
}
//string concat
strcat(sentence, secondbuff);
}
printf("%s\n", sentence);
fclose(fp);
}

Strings in C Language

How can you code this in C language if the output is like this? I need strings format of the code because our topic is strings.
#include <stdio.h>
#include <stdlib.h>
void main()
{
char my_string[50];
printf("Enter a word:");
scanf("%s", my_string);
printf("Enter a word:");
scanf("%s", my_string);
// Some unknown code here...
// this part is my only problem to solve this.
getch();
}
Output:
Hello -> (user input)
World -> (user input)
HWeolrllod -> (result)
Okay, you need to do some investigating. We don't, as a general rule, do people's homework for them since:
it's cheating.
you'll probably get caught out if you copy verbatim.
it won't help you in the long run at all.
The C library call for user input that you should use is fgets, along the line of:
char buffer[100];
fgets (buffer, sizeof(buffer), stdin);
This will input a string into the character array called buffer.
If you do that with two different buffers, you'll have the strings in memory.
Then you need to create pointers to them and walk through the two strings outputting alternating characters. Pointers are not an easy subject but the following pseudo-code may help:
set p1 to address of first character in string s1
set p1 to address of first character in string s1
while contents of p1 are not end of string marker:
output contents of p1
add 1 to p1 (move to next character)
if contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
while contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
Translating that into C will take some work but the algorithm is solid. You just need to be aware that a character pointer can be defined with char *p1;, getting the contents of it is done with *p1 and advancing it is p = p + 1; or p1++;.
Short of writing the code for you (which I'm not going to do), there's probably not much else you need.
void main()
{
char my_string1[50],my_string2[50]; int ptr;
ptr=0;
printf("Enter a word : ");
scanf("%s",my_string1);
printf("enter a word");
scanf("%s",my_string2);
while(my_string1[ptr]!='\0' && my_string2[ptr]!='\0')
{
printf("%c%c",my_string1[ptr],my_string2[ptr]);
ptr++;
}
if(my_string1[ptr]!='\0')
{
while(my_string1[ptr]!='\0')
{ printf("%c",my_string1[ptr]);
ptr++;
}
}
else
{
while(my_string2[ptr]!='\0')
{printf("%c",my_string2[ptr]);
ptr++;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char my_string1[50],my_string2[50];
int i,l1=1,l2=0;
printf("Enter a word:");
scanf("%s", my_string1);
printf("Enter a word:");
scanf("%s", my_string2);
l1=strlen(my_string1); /* Length of 1st string */
l2=strlen(my_string2); /* Length of 2nd string */
if(l1==l2)
{
for(i=0;i<l1;i++)
{
printf("%c%c",my_string1[i],my_string2[i]);
}
}
else
{
printf("Length of the entered strings do not match");
}
}
This is your required code.
You can see that output needs to be a String containing all chars of User String1 and User String2 one by one...
You can do this like...
//add #include<String.h>
int l1=strlen(s1);
int l2=strlen(s2);
if(l1!=l2)
{
printf("length do not match");
return 0;
}
char ansstr[l1+l2];
int i,j=0,k=0;
for(i=0;i<l1+l2;i=i+2)
{
ansstr[i]=s1[j];
ansstr[i+1]=s2[k];
j++;
k++;``
}
//ansstr is your answer
Ok, here's your code. Come on guys, if he asked here it means he can't solve this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char str1[] = "abcdefghijklmopq";
char str2[] = "jklm";
int len1 = strlen(str1);
int len2 = strlen(str2);
int c1 = 0, c2 = 0;
int max = (len1 > len2) ? len1 : len2 ;
char *result = malloc(len1 + len2);
for(c1 = 0; c1 <= max; c1++) {
if(c1 < len1)
result[c2++] = str1[c1];
if(c1 < len2)
result[c2++] = str2[c1];
}
result[c2] = 0;
printf("\n%s\n", result);
return 0;
}
Basically the loop picks up a character from str1 and appends it to result. Then it picks a character, which stands in the same position as the first from str2 and appends it to result, just as before. I increment c2 by 2 every time because I'm adding 2 chars to result. I check if c1 is bigger that the length of the strings because I want to copy only the characters in the string without the terminating \0. If you know that your strings have the same length you can omit these ifs.

Linux / C Check if a char contains spaces, the newline character or the tab character

I have a GtkEntry where the user has to enter an IP number or a hostname. When the button is pressed what the user typed into the entry is added to a char. How can I programmatically check if this char contains spaces, the newline character or the tab character? I don't need to remove them, just to know if they exist. Thanks in advance!
Take a look at character classification routines: man isspace.
Create a char array containing the characters of interest. Then use strchr() to search for the presence of the char in the string.
char charSet[] = { ' ', '\n', '\t', 0 };
char c;
// code that puts a character in c
if (strchr(charSet, c) != NULL)
{
// it is one of the set
}
The function you are looking for is strpbrk().
#include <stdio.h>
#include <string.h>
int check_whitespace (char *str)
{
char key[] = { ' ', '\n', '\t', 0 };
return strpbrk (str, key);
}
Let us suppose you mean that what is typed into the GtkEntry is added to an array of char (a string, in C terminology, provided that it is null terminated). Then to check if that array of char contains at least one or more of "space" characters (according to the locale, so we use isspace),
char *array;
int i;
//..
bool contains_space = false;
for(i = 0; i < strlen(array); i++) {
if ( isspace(array[i]) ) {
contains_space = true;
break;
}
}
// return contains_space
which can be turned into a function for example.
You might consider a function such as the following which counts the number of whitespace characters in the given string giving a positive integer is any are found (i.e. TRUE), zero if none are found (i.e. FALSE) and -1 on error.
#include <ctype.h>
static int
ws_count(char *s)
{
int n = -1;
if (s != NULL) {
char *p;
for (n = 0, p = s; *p != '\0'; p++) {
if (isspace(*p)) {
n++;
}
}
}
return n;
}

Resources