Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CS283
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
bgm47
CS283
Commits
6883e1b1
Commit
6883e1b1
authored
3 months ago
by
bgm47
Browse files
Options
Downloads
Patches
Plain Diff
update assignment 1
parent
70031efb
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
1-C-Refresher/stringfun.c
+252
-0
252 additions, 0 deletions
1-C-Refresher/stringfun.c
with
252 additions
and
0 deletions
1-C-Refresher/stringfun.c
0 → 100644
+
252
−
0
View file @
6883e1b1
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define BUFFER_SZ 50
//prototypes
void
usage
(
char
*
);
void
print_buff
(
char
*
,
int
);
int
setup_buff
(
char
*
,
char
*
,
int
);
int
count_words
(
char
*
,
int
,
int
);
void
reverse
(
char
*
,
int
,
int
);
void
printw
(
char
*
,
int
,
int
);
void
srplace
(
char
*
,
int
,
char
*
,
char
*
,
int
);
//prototypes for functions to handle required functionality
int
count_words
(
char
*
buff
,
int
len
,
int
str_len
)
{
int
word_count
=
0
;
int
in_word
=
0
;
for
(
int
i
=
0
;
i
<
str_len
;
i
++
)
{
if
(
*
(
buff
+
i
)
!=
' '
)
{
if
(
!
in_word
)
{
in_word
=
1
;
word_count
++
;
}
}
else
{
in_word
=
0
;
}
}
return
word_count
;
}
int
setup_buff
(
char
*
buff
,
char
*
user_str
,
int
len
)
{
char
*
src
=
user_str
;
char
*
dest
=
buff
;
int
count
=
0
;
int
space_flag
=
0
;
while
(
*
src
!=
'\0'
&&
count
<
len
)
{
if
(
*
src
==
' '
||
*
src
==
'\t'
)
{
if
(
!
space_flag
)
{
*
dest
++
=
' '
;
count
++
;
space_flag
=
1
;
}
}
else
{
*
dest
++
=
*
src
;
count
++
;
space_flag
=
0
;
}
src
++
;
}
if
(
*
src
!=
'\0'
)
{
return
-
1
;
}
while
(
count
<
len
)
{
*
dest
++
=
'.'
;
count
++
;
}
return
count
;
}
void
print_buff
(
char
*
buff
,
int
len
)
{
printf
(
"Buffer: ["
);
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
putchar
(
*
(
buff
+
i
));
}
printf
(
"]
\n
"
);
}
void
usage
(
char
*
exename
)
{
printf
(
"usage: %s [-h|c|r|w|x]
\"
string
\"
[other args]
\n
"
,
exename
);
}
void
reverse
(
char
*
buff
,
int
len
,
int
str_len
)
{
char
*
start
=
buff
;
char
*
end
=
buff
+
str_len
-
1
;
char
temp
;
while
(
start
<
end
)
{
temp
=
*
start
;
*
start
=
*
end
;
*
end
=
temp
;
start
++
;
end
--
;
}
}
void
printw
(
char
*
buff
,
int
len
,
int
str_len
)
{
int
word_index
=
1
;
int
word_length
=
0
;
printf
(
"Word Print
\n
----------
\n
"
);
for
(
int
i
=
0
;
i
<
str_len
;
i
++
)
{
char
current_char
=
*
(
buff
+
i
);
if
((
current_char
>=
'A'
&&
current_char
<=
'Z'
)
||
(
current_char
>=
'a'
&&
current_char
<=
'z'
)
||
(
current_char
>=
'0'
&&
current_char
<=
'9'
))
{
if
(
word_length
==
0
)
{
printf
(
"%d. "
,
word_index
);
}
putchar
(
current_char
);
word_length
++
;
}
else
if
(
current_char
==
' '
&&
word_length
>
0
)
{
printf
(
"(%d)
\n
"
,
word_length
);
word_index
++
;
word_length
=
0
;
}
}
if
(
word_length
>
0
)
{
printf
(
" (%d)
\n
"
,
word_length
);
}
printf
(
"
\n
Number of words returned: %d
\n
"
,
word_index
);
}
void
srplace
(
char
*
buff
,
int
len
,
char
*
old
,
char
*
new
,
int
str_len
)
{
char
temp
[
BUFFER_SZ
];
char
*
src
=
buff
,
*
dest
=
temp
;
int
old_len
=
strlen
(
old
),
new_len
=
strlen
(
new
);
int
replaced
=
0
;
while
(
*
src
!=
'\0'
&&
(
dest
-
temp
)
<
BUFFER_SZ
)
{
if
(
strncmp
(
src
,
old
,
old_len
)
==
0
)
{
if
((
dest
-
temp
)
+
new_len
>
BUFFER_SZ
)
{
break
;
// Prevent overflow
}
strncpy
(
dest
,
new
,
new_len
);
src
+=
old_len
;
dest
+=
new_len
;
replaced
=
1
;
}
else
{
*
dest
++
=
*
src
++
;
}
}
while
((
dest
-
temp
)
<
BUFFER_SZ
)
{
*
dest
++
=
'.'
;
}
if
(
replaced
)
{
memcpy
(
buff
,
temp
,
BUFFER_SZ
);
}
else
{
printf
(
"Not Implemented!
\n
"
);
exit
(
1
);
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
char
*
buff
;
//placehoder for the internal buffer
char
*
input_string
;
//holds the string provided by the user on cmd line
char
opt
;
//used to capture user option from cmd line
int
rc
;
//used for return codes
int
user_str_len
;
//length of user supplied string
//TODO: #1. WHY IS THIS SAFE, aka what if arv[1] does not exist?
//This is done to make that the command has the right syntax and all the minimal arguments
//needed for the subsequent operations to run with valid inputs, or to specify the type of error
//so the user may rectify it and find the right command that will work.
if
((
argc
<
2
)
||
(
*
argv
[
1
]
!=
'-'
)){
usage
(
argv
[
0
]);
exit
(
1
);
}
opt
=
(
char
)
*
(
argv
[
1
]
+
1
);
//handle the help flag and then exit normally
if
(
opt
==
'h'
){
usage
(
argv
[
0
]);
exit
(
0
);
}
//WE NOW WILL HANDLE THE REQUIRED OPERATIONS
//TODO: #2 Document the purpose of the if statement below
//It ensures that the user enters a command with at least one flag and two required parameters
//to proceed. Otherwise, an error will occur, and the syntax will assist them enter the right command.
if
(
argc
<
3
){
usage
(
argv
[
0
]);
exit
(
1
);
}
input_string
=
argv
[
2
];
//capture the user input string
//TODO: #3 Allocate space for the buffer using malloc and
// handle error if malloc fails by exiting with a
// return code of 99
buff
=
(
char
*
)
malloc
(
BUFFER_SZ
);
if
(
buff
==
NULL
)
{
exit
(
99
);
}
user_str_len
=
setup_buff
(
buff
,
input_string
,
BUFFER_SZ
);
if
(
user_str_len
<
0
)
{
printf
(
"Error setting up buffer
\n
"
);
free
(
buff
);
exit
(
2
);
}
switch
(
opt
)
{
case
'c'
:
rc
=
count_words
(
buff
,
BUFFER_SZ
,
user_str_len
);
//you need to implement
if
(
rc
<
0
){
printf
(
"Error counting words, rc = %d"
,
rc
);
exit
(
2
);
}
printf
(
"Word Count: %d
\n
"
,
rc
);
break
;
case
'r'
:
reverse
(
buff
,
BUFFER_SZ
,
user_str_len
);
break
;
case
'w'
:
printw
(
buff
,
BUFFER_SZ
,
user_str_len
);
break
;
case
'x'
:
if
(
argc
<
5
)
{
usage
(
argv
[
0
]);
free
(
buff
);
exit
(
1
);
}
srplace
(
buff
,
BUFFER_SZ
,
argv
[
3
],
argv
[
4
],
user_str_len
);
break
;
default:
usage
(
argv
[
0
]);
free
(
buff
);
exit
(
1
);
}
//TODO: #6 Dont forget to free your buffer before exiting
print_buff
(
buff
,
BUFFER_SZ
);
free
(
buff
);
exit
(
0
);
}
//TODO: #7 Notice all of the helper functions provided in the
// starter take both the buffer as well as the length. Why
// do you think providing both the pointer and the length
// is a good practice, after all we know from main() that
// the buff variable will have exactly 50 bytes?
//
// Both the pointer and the length must be provided since this
// will enable the function to monitor the buffer's length during and after each
// modification step to prevent overflow and to set up the buffer once the string
// operation is finished (ensuring that it always contains exactly 50 bytes).
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment