#include <stdio.h>
int any(char s1[], char s2[]) {
//converts to lower case
int c = 'a';
int i1 = 0;
while (s1[i1] != '\0') {
if (s1[i1] >= 'A' && s1[i1] <= 'Z')
s1[i1] += 32;
++i1;
}
int i2 = 0;
while (s2[i2] != '\0') {
if (s2[i2] >= 'A' && s2[i2] <= 'Z')
s2[i2] += 32;
++i2;
}
i1 = 0;
while (s1[i1] != '\0') {
i2 = 0;
while (s2[i2] != '\0') {
if (s1[i1] == s2[i2])
return i1;
++i2;
}
++i1;
}
return -1;
}
main() {
//printf("test");
printf("%d", any("This is fun", "fin"));
}
This code causes a segmentation fault and I'm pretty sure it happens when I try to set one of the chars in the array equal to an int. How do I not get a seg fault?
You are calling any with pointers to string constants. Attempting to modify these strings invokes undefined behavior.
Also note that the prototype for main should be int main(void) or int main(int argc, char *argv[]), and main should return 0 for successful operation.
You are implementing a case insensitive version of a generalized version of strchr with multiple characters, but you should not modify the argument strings, and you should rely on the functions from <ctype.h> instead of assuming ASCII.
Here is a better version:
#include <ctype.h>
#include <stdio.h>
int any(const char s1[], const char s2[]) {
int i1 = 0;
while (s1[i1] != '\0') {
int i2 = 0;
while (s2[i2] != '\0') {
if (tolower((unsigned char)s1[i1]) == tolower((unsigned char)s2[i2]))
return i1;
++i2;
}
++i1;
}
return -1;
}
int main(void) {
//printf("test");
printf("%d", any("This is fun", "fin"));
return 0;
}
Related
Write a function that, using the strrot function,
modifies each string of the given array s out of n strings.
The function prototype is:
void rot_all(char *s[], int n);
Here's my code I only don't know how to do the last function.
char rot3(char c) // Function shifts a letter by three spaces (eg 'a' -> 'd')
{
if (c >= 'A' && c <= 'Z') return c += 3;
if (c >= 'a' && c <= 'z') return c += 3;
return c;
}
void strrot(char *str)
{
int d = strlen (str);
for (int i = 0; i < d; i++)
{
str[i] = rot3(str[i]);
}
}
void rot_all(char *s[], int n)
{
}
int main ()
{
char str[23];
scanf("%s",str);
strrot(str);
printf("%s",str);
return 0;
}
The assumption is that c is a either lower or upper case letter. Using an assert() to document this.
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char rot3(char c) {
assert(isalpha(c));
char offset = isupper(c) ? 'A' : 'a';
return offset + (c - offset + 3) % ('Z' - 'A' + 1);
}
void strrot(char *str) {
for (int i = 0; str[i]; i++) {
str[i] = rot3(str[i]);
}
}
void rot_all(char *s[], int n) {
for(int i = 0; i < n; i++) {
strrot(s[i]);
}
}
int main () {
char *strs[] = {
strdup("Hello"),
strdup("World")
};
rot_all(strs, sizeof(strs) / sizeof(*strs));
for(int i = 0; i < sizeof(strs) / sizeof(*strs); i++) {
printf("%s\n", strs[i]);
free(strs[i]);
}
return 0;
}
and the output is:
Khoor
Zruog
I have a big problem with my function.
My program (C) is supposed to display the number of occurrences of a letter (Upper or lower case).
The program must handle 2 arguments and work as follows:
./rush2 “Just because I don’t care doesn’t mean I don’t understand!” a
4
I tried this :
#include <stdio.h>
int rush2(int argc, char **argv)
{
int i = 0;
int count_letter = 0;
while (argv[0][i] != '\0') {
if (argv[0][i] == argv[1][0]) {
count_letter = count_letter + 1;
}
i = i + 1;
}
printf("%d", count_letter);
return (count_letter);
}
int main (int ac, char **av)
{
rush2(ac, av);
return (0);
}
My function prints 0 or seg faults.
Please help me.
Try this:
#include <stdio.h>
void rush2(char str[], char c_lower)
{
char c_upper = c_lower - 32;
int i = 0;
int count_letter = 0;
while (str[i] != '\0')
{
if (str[i] == c_lower || str[i] == c_upper)
{
count_letter += 1;
}
i += 1;
}
printf("%d\n", count_letter);
}
int main (int argc, char *argv[])
{
rush2(argv[1], argv[2][0]);
return 0;
}
I want to get all vowel substrings from the given string.
Given string is 'auiouxaeibaou', get substrings from the given string like [auiou,aei,aou].
Here I tried something like this, but not getting the exact output.
bool isVowel(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
void substr(char str[], int low, int high)
{
printf("%.*s \n\n ", high-low+1, (str+low));
}
int main(int argc, const char *argv[]) {
char str[] = "aeixae";
int length = strlen(str);
int start_index = 0, end_index = 0;
for (int x=0; x<length; x++) {
char c = str[x];
if (isVowel(c) == false) {
end_index = x;
substr(str, start_index, end_index - 1 );
start_index = end_index + 1;
}
}
return 0;
}
your attempt was close. I just added the includes and made sure that the last part of the string also was printed. See the termination of the for loop and the if where you check for the vowel.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool isVowel(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
void substr(char str[], int low, int high)
{
printf("%.*s \n\n", high-low+1, (str+low));
}
int main(int argc, const char *argv[]) {
char str[] = "aeixae";
int length = strlen(str);
int start_index = 0, end_index = 0;
for (int x=0; x<=length; x++) {
if (x == length || !isVowel(str[x])) {
end_index = x;
substr(str, start_index, end_index - 1 );
start_index = end_index + 1;
}
}
return 0;
}
and this is the output:
gcc main.c && ./a.out
aei
ae
Nice program. Remember to use size_t as the proper type returned by strlen().
Well, if you want input to be auiouxaeibaou, you need to insert it at char str[] = "aeixae";
Great substr function!
You need to remember about the last substr from the string - when x reaches lenth, there is still one substring
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
bool isVowel(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
void substr(char str[], int low, int high)
{
printf("%.*s\n", high-low+1, (str+low));
}
int main(int argc, const char *argv[]) {
// ch-ch-ch-changes
char str[] = "auiouxaeibaou";
int length = strlen(str);
int start_index = 0, end_index = 0;
for (int x = 0; x < length; x++) {
char c = str[x];
if (isVowel(c) == false) {
end_index = x;
substr(str, start_index, end_index - 1 );
start_index = end_index + 1;
}
}
// ch-ch-ch-changes
end_index = length;
substr(str, start_index, end_index - 1 );
return 0;
}
but not getting the exact output.
why you don't have the expected result :
you miss the last sequence of vowel, to have it just replace for (int x=0; x<length; x++) by for (int x=0; x<=length; x++) because the null character is not a vowel (that does not produce illegal access)
when you have several consecutive non vowel you call anyway substr, to avoid that you need to memorize if had or not previously a vowel
The modifications gives that (I changed the input string) :
bool isVowel(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
void substr(char str[], int low, int high)
{
printf("%.*s \n\n ", high-low+1, (str+low));
}
int main(int argc, const char *argv[]) {
char str[] = "aeixaewwii";
int length = strlen(str);
int start_index = 0, end_index = 0;
bool wasVowel = false;
for (int x=0; x<=length; x++) {
char c = str[x];
if (isVowel(c) == false){
end_index = x;
if (wasVowel)
substr(str, start_index, end_index - 1 );
start_index = end_index + 1;
wasVowel = false;
}
else
wasVowel = true;
}
return 0;
}
BTW : 'y' is a vowel for me, you missed it in isVowel()
For fun, here is a simple way to do it without substrings, just print vowels as they come and add newlines the first time you hit a consonant.
#include <stdio.h>
#include <string.h>
int isVowel(char c){
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'){
return 1;
}
else{
return -1;
}
}
int main()
{
char my_str[] = "auiouxxxxxxaeibaou";
int todo_newline = 1; // prevent consecutive newlines
for(int i = 0; my_str[i] != '\0'; i++){
if(isVowel(my_str[i]) == 1){
printf("%c", my_str[i]);
todo_newline = 1;
}
else{
if(todo_newline == 1){ // print one newline
printf("%c", '\n');
todo_newline = -1; // don't print consecutive newlines
}
}
}
}
Alternative approach:
strspn(), strcspn() are the best tools here. #Gem Taylor
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "aeixae";
const char *s = str;
while (*(s += strcspn(s, "aeiou")) != '\0') { // skip letters that are not aeiou
size_t len = strspn(s, "aeiou"); // find length made up of aeiou
printf("<%.*s>\n", (int) len, s); // print sub string
s += len;
}
}
Output
<aei>
<ae>
I am trying to write a function who take a string and puts all the words in a 2d array, but I am getting a Segmentation fault error.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static int ft_countwords(char const *s, char c)
{
int nbr;
int i;
i = 0;
nbr = 0;
while (s[i])
{
if (s[i] != c)
{
nbr++;
while (s[i] != c)
i++;
}
else
{
while (s[i] == c)
i++;
}
}
return (nbr);
}
static char *ft_getword(char const *s, char c, int *start)
{
int i;
int word_size;
char *word;
i = 0;
word_size = *start;
while (s[word_size] && s[word_size] != c)
word_size++;
word = (char*)malloc(word_size - *start + 1);
while (s[*start] && s[*start] != c)
{
word[i] = s[*start];
i++;
*start++;
}
word[i] = '\0';
return (word);
}
char **ft_strsplit(char const *s, char c)
{
int row;
int i;
char **a;
a = NULL;
if (s)
a = (char**)malloc(sizeof(char*) * ft_countwords(s, c) + 1);
row = 0;
i = 0;
while (s[i] && row < ft_countwords(s, c))
{
if (s[i] != c && s[i])
{
a[row] = strdup(ft_getword(s, c, &i));
row++;
}
while (s[i] == c)
i++;
}
a[row] = '\0';
return (a);
}
int main(void)
{
int i;
char *test, **a;
test = strdup("__AAA_bbb__ccccc_DDDD___");
a = ft_strsplit((char const *)test, '_');
if (a)
{
i = 0;
while (a[i])
{
printf("%s\n", a[i]);
i++;
}
}
else
printf("(null)");
return (0);
}
I tested the first two functions and they work, but I cannot find the problem with the ft_strsplit function.
gcc ft_strsplit.c && ./a.out
Segmentation fault (core dumped)
Recompile with -g to get debugging information in your core dump. Then use gdb to analyze the core dump. You can get a backtrace with where and then you can use print to see the values of variables. You should be able to identify the problem from there.
Alternatively, add a lot of logging to your program to figure out what it's doing just before it crashes and you should be able to keep narrowing it down until you find the problem.
I have a program that takes a char array and calls the function convert. The function determines whether the character is a letter or number. The program is supposed to output the first letter it finds in the string. and the first numbers it finds in the string. My loop to stop looking for letters after it finds one isn't working.
Any thoughts?
Code is written in C using the Borland Compiler.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char **);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
if(c >= 1){
*charptr = &array[i];
c++;
}
else
break;
}
else if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
}
return x;
}
UPDATE:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char ** charptr);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c;
char b[512];
for (i=0;array[i] != 0;i++){
if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
else if (isalpha(array[i]))
{
c++;
if(c >= 1){
*charptr = &array[i];
}
}
}
return x;
}
You have a logic error. c is initialized to 0. There is a line to increment c but it is inside an if block that will never be true.
if(c >= 1){
*charptr = &array[i];
c++;
}
Catch 22???
Perhaps you meant to use:
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
// No need for checking the value of c
// return as soon you find an alphabet.
*charptr = &array[i];
break;
}
else if ( isdigit(array[i]))
// If you are looking for an alphabet only,
// why do you have this block of code???
x = 10*x + array[i] - '0';
}
return x;
}
Update
Perhaps, this is what you are looking for.
int convert (char array[], char ** charptr)
{
size_t i;
int x = 0;
size_t len = strlen(array);
// Set charptr to NULL in case there are no letters in the input.
*charptr = NULL;
for (i=0;i<len;i++){
if ( isalpha(array[i]))
{
*charptr = &array[i];
return x;
}
else if ( isdigit(array[i]))
{
x = 10*x + array[i] - '0';
}
}
return x;
}
int scanString(char array[],char * charptr)
{
int len = strlen(array);
int digs = 0;
int x = 0;
*charptr = 0;
for (int i=0;i<len;i++){
if (charptr == 0 && isalpha(array[i]))
{
*charptr = array[i];
}
else if (digs == 0 && isdigit(array[i])){
x = array[i] - '0';
digs = 1;
}
if(digs > 0 && charptr != 0)
break;
}
return x;
}
the spec says return the first character found so changed the charptr.