How can I define and call this code as a function? - c

I'm new to programming.Im learning from CS50. I'm not sure on how to define this code as a function.I want the function to return key[n].And how to call the function?
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
int n = strlen(argv[1]);
int key[n];
int k =0;
for( int i = 0; i < strlen(argv[1]); i++)
{
if(islower(argv[1][i]) != 0)
{
for(int j = 97; j < argv[1][i]; j++)
{
k++;
}
key[i] = k;
k = k*0;
}
if(isupper(argv[1][i]) != 0)
{
for(int j = 65; j < argv[1][i]; j++)
{
k++;
}
key[i] = k;
k = k*0;
}
}
}

The function can look for example the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int * f( const char *s )
{
int *key = NULL;
size_t n = strlen( s );
if ( n != 0 && ( key = calloc( n, sizeof( int ) ) ) != NULL )
{
for ( size_t i = 0; i < n; i++ )
{
unsigned char c = s[i];
if ( islower( c ) ) key[i] = c - 'a';
if ( isupper( c ) ) key[i] = c - 'A';
}
}
return key;
}
int main( int argc, char * argv[] )
{
if ( argc == 2 )
{
int *key = f( argv[1] );
if (key != NULL)
{
// some other code
free( key );
}
}
return 0;
}

A function is a block of code with an "in" and "out". You define a function to receive values from the outside with syntax like int key (int example){} and pass in values to your function call with key(1);.
Your main() is also a function. The values that main() receives are being used in your code right now.
Your own function (which you define outside of main()) can be done in many ways, but the easiest would be to simply keep almost all of the same code within main() while figuring out how to transport what main() received into yours.

Related

How to print a specific character from a string in C

I'm recently practicing looping. I learned how to print: for example home to h ho hom home. by using
#include <stdio.h>
#include <string.h>
int main (){
char s[100];
printf("Input string = ");
scanf("%[^\n]", s);
for (int i=1; i<=strlen(s); i++){
for(int j = 0; j<i; j++)
printf("%c", s[j]);
printf("\n");
}
return 0;
How can i reverse it so it can be
home
hom
ho
h
instead? thank you.
It is easy to do. For example
for ( size_t i = strlen( s ); i != 0; i-- )
{
for ( size_t j = 0; j < i; j++ )
{
putchar( s[j] );
}
putchar( '\n' );
}
Another way is the following
for ( size_t i = strlen( s ); i != 0; i-- )
{
printf( ".*s\n", ( int )i, s );
}
provided that an object of the type int is able to store the length of the passed string.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
int main( void )
{
const char *s = "home";
for (size_t i = strlen( s ); i != 0; i--)
{
printf( "%.*s\n", ( int )i, s );
}
}
The program output is
home
hom
ho
h
You could loop over the string using putc, but it might also be helpful to understand the destructive approach that shortens the string and uses %s to print strings. eg:
#include <stdio.h>
#include <string.h>
int
main(int argc, char **argv)
{
char *s = argc > 1 ? argv[1] : strdup("home");
for( char *e = s + strlen(s); e > s; e -= 1 ){
*e = '\0';
printf("%s\n", s);
}
return 0;
}
Note that this approach is destructive. When complete, the string is null. As an exercise, it might be helpful to fix that.
You'll basically go backwards in your loop.
Instead of:
for (int i=1; i<=strlen(s); i++){
You'd have
for (int i=strlen(s); i>0; i--){

I am writing C function that convert lowercase char to upper case char with using ASCII but Output is not correct

Okay, So I start working on this, I have code below;
+I also have strlen("any string here") func that return len of any str in decimal just keep in your mind.
I take a lover case let's say a, then a will be equal some decimal num in ASCII table then I subtract 32 to get A.
Sadly this is not working, any idea for this?
Thank you for all help and your time!
int uppercase(char sent[]) {
for(int i=0; i <= strlen(sent); ++i) {
if(sent[i]>='a' && sent[i]<='z')
sent[i] -= 32;
}
The function is declared as having the return type int but returns nothing.
int uppercase(char sent[]) {
for(int i=0; i <= strlen(sent); ++i) {
if(sent[i]>='a' && sent[i]<='z')
sent[i] -= 32;
}
In general for a function that deals with strings the condition of the for loop should look at least like
for(int i=0; i < strlen(sent); ++i) {
Though it is better to write the loop like
for( size_t i = 0, n = strlen(sent); i < n; ++i ) {
However there is no great sense to use the function strlen in the function uppercase. Its call is redundant.
Pay attention to that you may not change a string literal. Any attempt to change a string literal results in undefined behavior.
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
Also it is better not to use the magic number 32.
The function can be written the following way as it is shown in the demonstrative program below.
#include <stdio.h>
char * uppercase( char *s )
{
for ( char *p = s; *p; ++p )
{
if ( 'a' <= *p && *p <= 'z' ) *p = *p & ~' ';
}
return s;
}
int main(void)
{
char s[] = "hello world!";
puts( s );
puts( uppercase( s ) );
return 0;
}
The program output is
hello world!
HELLO WORLD!
As for the function strlen then it is better to use another name for the function because it will conflict with the standard C function strlen. And the function itself can be defined the following way
size_t string_len( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
This code can help you
#include <stdio.h>
#include <string.h>
void uppercase(char T[],int k)
{
int i=0;
while(i<k)
{
if(T[i]>='a'&&T[i]<='z')
{
T[i]=(char)((int)T[i]-32);
}
i++;
}
i=0;
while(i<k)
{
printf("%c",T[i]);
i++;
}
printf("\n");
}
int main()
{
char T[]="good morning !";
int k=sizeof(T);
uppercase(T,k);
}
This one will work:
#include <stdio.h>
#include <string.h>
void uppercase(char sent[]) {
for (int i = 0; i < (int)strlen(sent); i++) {
if (sent[i] >= 'a' && sent[i] <= 'z') {
sent[i] -= 32;
}
}
}
int main(int argc, char* argv[]) {
if (argc > 1){
uppercase(argv[1]);
puts(argv[1]);
}
return 0;
}
It compiles without any errors and warnings (using clang), even with options -pedantic -Wall -Wextra.
/*
Parsing the string, then making the letters to uppercase.
*/
#include <stdio.h>
#include <limits.h>
int strlen(char s[]){ //String length function
int i;
for (i = 0; s[i] != '\0'; i++);
return i;
}
void uppercase(char sent[]) {
for(int i=0; i < strlen(sent); ++i) {
if(sent[i]>='a' && sent[i]<='z')
sent[i] += 32;
}
printf("%s", sent);
}
this is a whole tab of my whole work. when i try uppercase("hello world"); it giving me core dumped console problem.

number characters from input

bool in_array(char a[], char input, int len){
for (int l = 0; l < len; l++){
}
}
return false;
}
int main(void) {
char i = 'l';
int count = 0;
int count_d = 0;
char a[1000] = {0};
else{
count_d++;
}
}
printf("%d\n", count_d);
}
this is the code i have but this returns numbers of times it has duplicated
as there are two characters a and b
If you have learnt only arrays and do not know how to allocate memory dynamically then use a second array to store unique duplicated characters.
Here is a demonstrative program.
#include <stdio.h>
#include <stdbool.h>
bool in_array( const char a[], size_t n, char c )
{
size_t i = 0;
while ( i != n && a[i] != c ) i++;
return i != n;
}
int main(void)
{
enum { N = 128 };
char a[N];
char b[N / 2];
size_t count_duplicates = 0;
size_t count = 0;
char c;
while ( count < N && scanf( " %c", &c ) == 1 )
{
if ( !in_array( a, count, c ) )
{
a[count++] = c;
}
else if ( !in_array( b, count_duplicates, c ) )
{
b[count_duplicates++] = c;
}
}
printf( "There are %zu duplicated character(s).\n", count_duplicates );
return 0;
}
If to enter the sequence of characters
aaabbaaac
then the program output will be
There are 2 duplicated character(s).
i hope it will help you :
`#include <unistd.h>
#include <stdio.h>
#include <string.h>
int in_a(char *a, char c)
{
for (int i = 0; i < strlen(a); i++)
if (a[i] == c)
return 0;
return (1);
}
int main(int ac, char **av)
{
int count_duplicates = 0;
int same = 0;
char old = 0;
char new[128] = {0}; // i
int count = 0;
char *a = av[1];
while (a[count] != '\0') {
if (old != a[count] && in_a(new, a[count])) {
same = 0;
}
if (a[count] == old && same != 1) {
count_duplicates += 1;
same = 1;
}
old = a[count];
new[count] = a[count];
count += 1;
}
printf("%i\n", count_duplicates);
return (0);
}`

Parsing a command line command without string library

So i am trying to parse a command from a command line like:
cd /mnt/cdrom
comes to
name = "cd"
argc = 2
argv = {"cd", "/mnt/cdrom", NULL}
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
void parse(char* line, command_t* command) {
// TODO: Check if string is empty or null
while (line[i] != ' ' && line[i] != '\0')
i++;
if (line[i] == ' ') {
}
// TODO: Split the string on whitespace -> should become an array of char
// TODO: The first string is the command, the length of tokens[1:] is the length of the arguments, and tokens[1:] are the arguments
// TODO: Create/fill-in the command struct with the data from above
}
That is as far as i have made it im not really sure how to split it at this point without string functions.
Well it's in haste solution, but it works.. Of course you need to dynamically allocate memory in parse function with some kind of list for example (for different arguments) and some kind of buffer for current argument processing.
#include <stdio.h>
#include <stdlib.h>
#define MAX_TOKEN 5
#define MAX_LENGTH 64
void copy_str( char* dst, char* src, int size ) {
int i = 0;
for( i = 0; i < size; ++i ) {
dst[i] = src[i];
}
}
char** parse( char* line, int size, int* argc ) {
int i = 0, j = 0;
char** argv = NULL;
argv = (char**)calloc( MAX_TOKEN, sizeof(char*) );
for( i = 0; i < MAX_TOKEN; ++i ) {
argv[i] = (char*)calloc( MAX_LENGTH, sizeof(char) );
}
for( i = 0; i < size; ++i ) {
if( line[i] == ' ' ) {
copy_str( argv[*argc], line + j, i - j );
j = i + 1; // length of token
(*argc)++;
}
}
// copy last
copy_str( argv[*argc], line + j, i - j );
(*argc)++;
return argv;
}
int main( ) {
int t = 0, i;
char* s = "cd /mnt/cdrom";
char** argv = parse( s, 13, &t );
for( i = 0; i < t; ++i ) {
printf( "%s\n", argv[i] );
}
t = 0;
s = "ls -l /home/";
argv = parse( s, 12, &t );
for( i = 0; i < t; ++i ) {
printf( "%s\n", argv[i] );
}
return 0;
}

How to write a getline function in C?

I know that getline is C++ standard but I need to read a line of digits:
123856
and save it to an array. But how to do this without spaces between given (as input) digits? I want a user input to be:
123856 (with no spaces) and then save it to an array (n element array) and after that, I want my array to look like this:
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 8;
array[4] = 5;
array[5] = 6;
But how to make it in C, without a getline?
This is NOT what I want:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
int main(int argc, char **argv)
{
int t[4];
int i;
for(i=0; i<4; i++)
scanf("%d", &t[i]);
for(i=0; i<4; i++)
printf("%d\n", t[i]);
return 0;
}
If I understood you correct, the following should do it:
read the whole line
loop through the string as long as you get digits or the string ends
for every digit, place it's value in your array and increase the index by 1
while( ( c = getchar()) != EOF && c != '\n' && i < max ) {
/* If desired, add check for value outside of 0-9 */
array[ i++ ] = c - '0';
...
}
char arr[] = "1234567";
int intarr[10];
int count = 0;
for (char* ptr = arr; *ptr; ptr++) {
intarr[count] = *ptr - '0';
count++;
}
try this
#include <stdio.h>
#include <string.h>
main (int argc, char *argv[])
{
FILE *f;
int i=0;
int j=0;
char output[100];
char* output1[100];
char string[100];
char delims1[] = " ";
char delims2[] = "*";
char* result = NULL;
char* result3 = NULL;
int num;
//for (j=0; j<2; j++)
//{
//printf("%s",delims9[6]);
//}
f = fopen("text.txt","r");
//
while( fgets(string,sizeof(string),f) )
{
result = strtok( string, delims1 );
while( result != NULL )
{
output1[i]=result;
printf("%s\n",output1[i]);
result = strtok( NULL, delims1 );
i++;
}
for (num = 0; num < 100; i++ ) //
{ // Error On this array
printf("%s\n", output1[i]); //
} //
}
printf("\n%d",i/3+1);
return 0 ;
}
Ok, without using any string.
int digits = 123856;
int numofdigits = 1 + floor(log10(digits));
int digits_arr[numofdigits];
int i;
for(i = numofdigits-1; i >= 0; i--) {
digits_arr[i] = (int)floor(digits / pow(10, i)) % 10;
}
Try the below link... Same question asked here and get solution....
convert an integer number into an array
char * convertNumberIntoArray(unsigned int number) {
unsigned int length = (int)(log10((float)number)) + 1;
char * arr = (char *) malloc(length * sizeof(char)), * curr = arr;
do {
*curr++ = number % 10;
number /= 10;
} while (number != 0);
return arr;
}

Resources