C, turning camel text into snake text - c

I am total beginner, I want to make an application that for each lower camel case word supplied as a command line argument will print it's snake case equivalent. Also turns big letters into smaller ones and makes between them "_".
Example:
./coverter Iwant tobe famousAlready.
output:
i_want
tobe
famous_already
I have found some code to make the letters smaller, and output words in the command line separately. But I have no clue how to put them together, how to appeal into single character in function main? Is this even possible?
#include <stdio.h>
int main (int argc, char* argv[]);
{
printf("argc = %d\n", argc);
for (int i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
}
char change()
{
char words[30];
int ch;
printf ("Give the words: ");
int i=0;
while ((ch=getchar()) != EOF)
{
slowko[i]=ch;
if(isupper(slowko[i])) /* isupper, robi rzeczy - sprawdza czy */
/* litera z sekwencji jest duza */
{
slowko[i]=tolower(ch); /*zamien duzy znak na maly*/
printf("_");
}
else if(slowko[i] == ' ')
{
printf("\n");
}
printf ("%c", slowko[i]);
i++;
}
}

You have command line arguments inside argv array starting from index 1. Maybe, it's not the most elegant solution, but it works:
#include <stdio.h>
#include <ctype.h>
void print_snake_case(const char str[]){
int i = 0;
while (str[i] != '\0')
{
if(isupper((unsigned char) str[i])) /*isupper, robi rzeczy - sprawdza czy litera z sekwencji jest duza*/
{
const char ch = tolower((unsigned char) str[i]); /*zamien duzy znak na maly*/
/*
Different order of "_": it should be placed after
the character in case it's at the beginning of the word.
And before the character if it's not at the beginning.
*/
if(i != 0)
{
printf("_");
printf ("%c", ch);
}
else
{
printf ("%c", ch);
printf("_");
}
}
else
printf ("%c", str[i]);
i++;
}
printf("\n");
}
int main (int argc, char* argv[])
{
for (int i = 1; i < argc; i++)
{
print_snake_case(argv[i]);
}
}
Output:
$ ./converter Iwant tobe famousAlready
i_want
tobe
famous_already

Related

How can I pass a stdin as an argument for my function?

My first program. I would like it if the user enters a word made of letters and then it uses my loop function to output mixed up even and odd characters. Currently I cannot get it to compile. Bonus points if someone can show me how to loop the users input so after it asks the size to make the array, it prompts the user that many times for an "element" or word so that the function can scramble it and output it.
#include <stdio.h>
char transform(char str[]);
int main()
{ //Declare an array and size variable
int size = 0;
char str[size];
printf("How many elements?");
scanf("%d", &size);
printf("Please type an element: ");
//Get input from user
str[0] = scanf("%s", str);
transform(str);
printf("Please type another element: ");
//Get another input from user
str[1] = scanf("%s", str);
transform(str);
//This is the loop function that I programmed
char transform(char str[]);
{
//Loop that prints even characters
for (int i = 0; str[i] != '\0'; i++)
{
if(i % 2 == 0)
{
printf("%c", str[i]);
}
} //Space between even/odd characters
printf(" ");
//Loop that prints odd characters
for (int i = 0; str[i] != '\0'; i++)
{
if(i % 2 != 0)
{
printf("%c", str[i]);
}
}
printf("\n");
return 0;
}
}
#include <stdlib.h>
#include <stdio.h>
char transform(char str[]);
int main()
{ //Declare an array and size variable
int size = 0;
printf("How many elements?");
scanf("%d", &size);
for (int i = 0; i < size; ++i)
{
printf("Please type an element: ");
char str[2048]; //declare a wide buffer to be able to store lots of chars
scanf("%s", str);
transform(str);
}
return 0;
} //end your main here, by putting closing brace
char transform(char str[]) //define transform without semicolon, and outside of main
{ //This is the loop function that I programmed
//Loop that prints even characters
for (int i = 0; str[i] != '\0'; i++)
{
if (i % 2 == 0)
printf("%c", str[i]);
} //Space between even/odd characters
printf(" ");
//Loop that prints odd characters
for (int i = 0; str[i] != '\0'; i++)
{
if (i % 2 != 0)
printf("%c", str[i]);
}
printf("\n");
return 0;
}

How do I let the user multiply two numbers as well as let them multiply a string?

What I mean by this is, I'm writing a program where the user inputs a string along with a '*' character and any number, and the program multiplies the string the user entered by that number
Please enter a string you'd like multiplied: horse*3
output:
horsehorsehorse
What I'd like to do is, if that string happens to be a number, then multiply the two numbers like you normally would
Please enter a string you'd like multiplied: 2*2
output:
4
I'm putting my code down below.
int multStr(char *strMult) //strMult is character array for initial input
{
//printf("\nRedirected to here!\n");
printf("Please enter a string and number you'd like to multiply by: ");
scanf(" %[^\n]s", strMult); //User scans in the string intended for multiplication
char string[255]; //Character array for the string part
char number[255]; //Character array for the number the string is to be multiplied by
int counter=0;
int i;
for(i=0;strMult[i] != '*'; i++)
{
string[i] = strMult[i];
counter++;
}
if(string[i] >= '0' && string[i] <= '9')
{
int strNum = myAtoi(string);
printf("String: %d", strNum);
}
else
{
printf("String: %s\n", string);
}
counter++;
for(i=0; strMult[counter] != '\0'; counter++, i++)
{
number[i] = strMult[counter];
}
//number[i+1] = '\0';
printf("Number: %s\n", number);
int num = myAtoi(number);
//printf("Number after convert: %d\n", num);
for(i=0; i<num; i++)
{
printf("%s", string);
}
printf("\n");
return(0);
}
strMult is a char array I called from main. I was not able to use stdlib, so I created my own Atoi function
You have a couple issues here. The first thing you're doing is splitting the string into two char[]s string and number. You seem to do that ok. The next thing you need to do is to check that string is a number.
if(string[i] >= '0' && string[i] <= '9')
{
int strNum = myAtoi(string);
printf("String: %d", strNum);
}
else
{
printf("String: %s\n", string);
}
This is what you're using, but note that it has no consequence to the rest of the program. Your number is local to the if block, and then it goes away, so you cannot use it later. What you want to do, is make the number available later.
int isNumber = 1;
int strNum;
for(int k = 0; k < i; k++){
if( string[k] >= '0' && string[k]<='9' ){
//continue checking
}else{
isNumber=0;
}
}
if (isNumber==1){
strNum = myAtoi(string);
} else{
// print your string or some such.
}
Note that I check all of the characters in the string, and not just the '*' which is the character at the i'th position. That way, if somebody enters horse42*2, it will think it is a string.
Also, you can improve this by checking the values as you separate out the number.
Regular expressions are a useful tool for parsing user input. Reading unconstrained user input with scanf is dangerous because unexpectedly long input will overflow the buffer.
Here is an example that use getline for reading input safely and regular expressions to sort out the format for the user input.
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#define TERM "(([[:digit:]]+)|([[:alpha:]]+))"
void string_by_number(int number, char *string)
{
printf("number %d string %s\n", number, string);
for (int i = 0; i < number; ++i) {
printf("%s", string);
}
printf("\n");
}
int main(int argc, char *argv[])
{
regex_t re;
regmatch_t capture[7];
if (regcomp(&re, TERM "[[:space:]]*[*][[:space:]]*" TERM, REG_EXTENDED)) {
fprintf(stderr, "error in regular expression pattern\n");
return 1;
}
char *line = NULL;
size_t line_size = 0;
printf("Please enter a string you'd like multiplied: ");
while (0 < getline(&line, &line_size, stdin)) {
if (regexec(&re, line, 7, capture, 0)) {
printf("Unexpected input '%s'\n", line);
continue;
}
int format = 0;
char *lhs_string = NULL;
int lhs_number;
char *rhs_string = NULL;
int rhs_number;
if (capture[2].rm_so >= 0) {
format ^= 0x01;
lhs_number = strtol(&line[capture[2].rm_so], NULL, 10);
}
else {
lhs_string = &line[capture[3].rm_so];
line[capture[3].rm_eo] = '\0';
}
if (capture[5].rm_so >= 0) {
format ^= 0x02;
rhs_number = strtol(&line[capture[5].rm_so], NULL, 10);
}
else {
rhs_string = &line[capture[6].rm_so];
line[capture[6].rm_eo] = '\0';
}
switch (format) {
case 0x00: printf("Can't do 'string' * 'string'\n"); break;
case 0x01: string_by_number(lhs_number, rhs_string); break;
case 0x02: string_by_number(rhs_number, lhs_string); break;
case 0x03: printf("%d\n", lhs_number * rhs_number); break;
}
printf("\nPlease enter a string you'd like multiplied: ");
}
free(line);
regfree(&re);
return 0;
}

Modifying a program to run as command line arguments in C

Full disclosure, this is an assignment for a class I have to do. We have a program that checks if two words are anagrams. We are supposed to modify it so that we can enter the words as command lines in a program. For instance: (./a.out hello elloh: is an anagram... ./a.out hello world: Not an anagram).
Here is the original program:
#include <stdio.h>
#define N 26
int main()
{
char ch;
int letter_counts[N]= {0};
int i;
int count =0;
printf("enter a word: ");
while((ch=getchar())!= '\n')
{
letter_counts[ch - 'a']++;
}
for(i =0;i<N;i++)
printf("%d", letter_counts[i]);
printf("enter the second word: ");
while((ch=getchar())!= '\n')
{
letter_counts[ch - 'a']--;
}
for(i =0;i<N;i++)
printf("%d", letter_counts[i]);
for(i =0;i<N;i++)
if(letter_counts[i]==0)
count++;
if(count == N)
printf("The words are anagrams.\n");
else
printf("The words are NOT anagrams.\n");
return 0;
}
Now here is what I have so far:
#include <stdio.h>
#define N 26
/*
This program is a modified version of anagram.c so that the words run as command-line arguments.
*/
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf("Incorrect number of arguments");
return 0;
}
char ch;
int letter_counts[N]= {0};
int i;
int count =0;
//int k;
//for (k = 1; i < argc; i++)
//{
while((ch=getchar())!= '\n')
{
letter_counts[ch - 'a']++;
}
for(i =0;i<N;i++)
printf("%d", letter_counts[i]);
while((ch=getchar())!= '\n')
{
letter_counts[ch - 'a']--;
}
//for(i =0;i<N;i++)
//printf("%d", letter_counts[i]);
for(i =0;i<N;i++)
if(letter_counts[i]==0)
count++;
int k;
int j;
for (k = 1; i < argc; i++)
{
for (j = 0; j < N; j++)
{
if (count == N)
{
printf("%s and %s are anagrams\n", argv[k], argv[k + 1]);
break;
}
else
printf("The words are NOT anagrams. \n");
}
}
if(count == N)
printf("The words are anagrams.\n");
else
printf("The words are NOT anagrams.\n");
//}
return 0;
}
The output (if the number of arguments is correct) is always :
0000000000000000000000000
0000000000000000000000000
These are anagrams
What am I doing wrong here and what is the best way to go about this?
Thank you for any help I really appreciate it.
You are using getchar() which reads from STDIN, which isn't what you want to do if you're getting your words from command-line arguments. Instead you want to look at argv:
for (char *c = argv[1]; *c != NULL; c++) {
letter_counts[*c - 'a']++;
}
and
for (char *c = argv[2]; *c != NULL; c++) {
letter_counts[*c - 'a']--;
}
More about argc and argv: http://crasseux.com/books/ctutorial/argc-and-argv.html
To not solve your homework for you I'll show you how to use argc and argv on a different program that just checks if the first parameter reversed equals the second:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 3) {
printf("Usage: %s first_word second_word\n\n", argv[0]);
return EXIT_SUCCESS;
}
char const *first = argv[1];
char const *second = argv[2];
size_t first_length = strlen(first);
size_t second_length = strlen(second);
if (first_length != second_length) {
puts("The words are NOT semordnilaps.\n");
return EXIT_SUCCESS;
}
for (size_t first_index = first_length, second_index = 0; first_index; --first_index, ++second_index) {
if (first[first_index - 1] != second[second_index]) {
puts("The words are NOT semordnilaps.\n");
return EXIT_SUCCESS;
}
}
puts("The words are semordnilaps.\n");
}
Modified program torun from command line argumement. Below is working code snippet for you.
Here we pass two command line arguments with program name. while ((ch = argv[1][len]) != '\0') retrieve the char by char from first arguments and while ((ch = argv[2][len]) != '\0') retrieve the same from the second and rest of the logic remains same.
#include <stdio.h>
#define N 26
int main(int argc, char *argv[])
{
if( argc != 3)
{
printf("Incorrect argumemts\n");
return 0;
}
char ch;
int letter_counts[N]= {0};
int i;
int count =0;
int len=0;
while ((ch = argv[1][len]) != '\0')
{
letter_counts[ch - 'a']++;
len++; /* moving index */
}
for(i =0;i<N;i++)
printf("%d", letter_counts[i]);
len=0;
while ((ch = argv[2][len]) != '\0')
{
letter_counts[ch - 'a']--;
len++; /* moving index */
}
for(i =0;i<N;i++)
printf("%d", letter_counts[i]);
for(i =0;i<N;i++)
if(letter_counts[i]==0)
count++;
if(count == N)
printf("The words are anagrams.\n");
else
printf("The words are NOT anagrams.\n");
return 0;
}

Find missing lower-case letters that are not in a series of words

As stated in the title I am trying to find all lower-case letters that are not in a series of words. There are no upper-case letters, digits, punctuation, or special symbols.
I need help fixing my code. I am stuck and do not know where to go from here.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void){
int letters[26];
char words[50];
int i = 0, b = 0;
printf("Enter your input : ");
scanf("%s", words);
for(i = 0; i < 26; i++){
letters[i] = 0;
}
while(!feof(stdin)){
for(b = 0; b < strlen(words) - 1; b++){
letters[ words[b] - 'a']++;
scanf("%s", words);
}
}
printf("\nMissing letters : %c ", b + 97);
return 0;
}
My output is giving me some random letter that I do not know where it is coming from.
Here is a working first implementation.
As well as the comments that have already been made, you should use functions wherever possible to separate out the functionality of the program into logical steps. Your main function should then just call the appropriate functions in order to solve the problem. Each function should be something that is self contained and testable.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_INPUT 20 /* Max input to read from user. */
char *readinput(void);
void find_missing_lower_case(char *, int);
int main()
{
char *user_input = readinput();
int len_input = strlen(user_input);
printf("user input: %s\n", user_input);
printf("len input: %d\n", len_input);
find_missing_lower_case(user_input, len_input);
/* Free the memory allocated for 'user_input'. */
free(user_input);
return 0;
}
char *readinput()
{
char a;
char *result = (char *) malloc(MAX_INPUT);
int i;
for(i = 0; i < MAX_INPUT; ++i)
{
scanf("%c", &a);
if( a == '\n')
{
break;
}
*(result + i) = a;
}
*(result + i) = '\0';
return result;
}
void find_missing_lower_case(char *input, int len_input)
{
int a = 97; /* ASCII value of 'a' */
int z = 122; /* ASCII value of 'z' */
int lower_case_chars[26] = {0}; /* Initialise all to value of 0 */
/* Scan through input and if a lower case char is found, set the
* corresponding index of lower_case_chars to 1
*/
for(int i = 0; i < len_input; i++)
{
char c = *(input + i);
if(c >= a && c <= z)
{
lower_case_chars[c - a] = 1;
}
}
/* Iterate through lower_case_chars and print any values that were not set
* to 1 in the above for loop.
*/
printf("Missing lower case characters:\n");
for(int i = 0; i < 26; i++)
{
if(!lower_case_chars[i])
{
printf("%c ", i + a);
}
}
printf("\n");
}
I figured it out and this is the code I used.
int main(void)
{
int array[26];
char w;
int i=0;
for(i=0; i<26; i++) {
array[i]=0; }
printf("Enter your input: ");
scanf("%c", &w);
while(!feof(stdin)) {
array[w-97] = 1;
scanf("%c", &w); }
printf("Missing letters: ");
for(i=0; i<26; i++) {
if(array[i] == 0) {
printf("%c ", i+97); }
}
printf("\n");
return 0;
}

Arrays in a Palindrome program

So I made a program where I have to input a word and it displays if it is a palindrome (a word that is the same both ways) or not.
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]){
char word;
int length, counter;
printf("Please enter a word: ");
scanf("%c", &word);
int flag = 1;
for (counter = 0; counter < length && flag; counter++) {
printf("%c\t %c", word[counter], word[length - counter])
if (word[counter] == word[length - counter - 1]){
flag = 0;
}
}
if (flag) {
printf("%c is a palindrome!", word);
}
else {
printf("%c is NOT a palindrome!", word);
}
}
I set it up so that it displays each letter side by side. If a letter isn't the same then the flag is "thrown"(set to 0) and this will end the program saying: "word is NOT a palindrome!"
I get an error at the part where it says word[counter] saying it isn't a subscripted value. What can I do to make this work? Is there anything else I am doing wrong?
This char word; is not an array. This char word[100]; is an Array. Also you read a single character using scanf("%c", &word); not a word (as in a string or series of characters). Use:
fgets (word , 100 , stdin)
Also length is not initialized, so it will lead to UB.
Make this modifications in your program.It will run fine.
#include <stdio.h>
#include <string.h>
int main()
{
char word[100];
int length, counter;
printf("Please enter a word: ");
scanf("%s",word);
length=strlen(word);
int flag = 1;
for(counter = 0; counter < length/2 && flag; counter++)
{
if (word[counter] != word[length-counter-1])
{
flag = 0;
break;
}
}
if (flag)
{
printf("%s is a palindrome!\n", word);
}
else {
printf("%s is NOT a palindrome\n!", word);
}
}
****************************************************************
* Simple Array Palindrome Program *
****************************************************************/
#include <iostream>
using namespace std;
int main (){
int arr_size;
int flag=0;
/*****************************************
* Array Size *
*****************************************/
cout<<"Enter The Array Size: \n->arr[";
cin>>arr_size;cout<<" ]";
int arr[arr_size];
/*****************************************
* User_Input *
*****************************************/
for(int i=0;i<arr_size;i++){
cout<<"Enter Value For Arr[ "<<i<<" ] -> ";
cin>>arr[i];
}
/*****************************************
* Palindrome_Check *
*****************************************/
for(int k=0,j=arr_size-1;k<arr_size && j>-1;k++)
{
if(arr[i]==arr[j];
{
flag++;
}
}
/*****************************************
* Flag Check *
*****************************************/
if(flag==arr_size) {
cout<<"Array Is Palindrome: ";
}
else
{
cout<<"Array Is Not Palindrome: ";
}
}

Resources