C :: Aufgabe #41
3 Lösungen
Schleifen - Reguläre Ausdrücke - Eingabe auf 'fred' prüfen
Anfänger - C
von Gustl
- 25.06.2013 um 15:24 Uhr
Schreiben Sie ein Programm, das jede Eingabezeile ausgibt, in der "fred" vorkommt. (Andere Eingabezeilen sollen nicht behandelt werden.) Das Muster soll auch Fred, Frederick, Alfred oder FrEd finden? (Egal ob die Buchstaben klein oder groß geschrieben werden.
Lösungen:
/********************************************
* fred_2.c search pattern in input stream
* using basic regular expressions
*
* OS : GNU/Linux
* compile: gcc -Wall -o fred fred_2.c
* example: echo Freddy|./fred -i fred
*
* devnull 28-06-2013
********************************************/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <regex.h>
#define STR_LEN 62
#define BUF_LEN 254
/**********
* GLOBALS
**********/
regex_t regex;
/************
* functions
************/
/* print usage on stderr */
void usage_exit( int exit_code )
{
fprintf( stderr, "Usage: fred [-i] pattern\n" );
exit(exit_code);
}
/* execute regular expression on a single line */
int parseln( const char* pstr )
{
char msgbuf[STR_LEN];
int rc = regexec( ®ex,pstr,0,NULL,0 );
switch (rc) {
case 0:
return 0;
break;
case REG_NOMATCH:
return 1;
break;
default:
regerror( rc, ®ex, msgbuf, sizeof(msgbuf) );
fprintf( stderr, "Regex match failed: %s\n", msgbuf );
return -1;
}
}
/* read input line from stdin */
int readln( char *line, int stripLF )
{
int len;
if (fgets(line, BUF_LEN, stdin) != NULL) {
line[BUF_LEN]='\0';
len=strlen(line);
if (stripLF) {
if (line[len-1] == '\n') {
line[len-1] = '\0';
len--;
}
}
return len;
}
else
return -1;
}
/*********
* main
*********/
int main( int argc, char **argv )
{
char linebuf[BUF_LEN+1];
char pattern[STR_LEN+1];
int opt, opt_icase=0;
int cline,slen;
/* check options [ih] */
while ((opt = getopt( argc, argv, "ih" )) != -1) {
switch(opt) {
case 'i': opt_icase=1; break;
case 'h': usage_exit(EXIT_SUCCESS); break;
default : usage_exit(EXIT_FAILURE);
}
}
/* check args: search string/pattern */
if (argc-optind != 1)
usage_exit(EXIT_FAILURE);
strncpy( pattern, argv[optind], STR_LEN );
pattern[STR_LEN] = '\0';
slen=strlen(pattern);
if (slen == 0) {
fprintf( stderr, "empty search string\n" );
return 2;
}
/* compile basic regular expression */
if (regcomp(®ex, pattern, REG_NOSUB|((opt_icase)?REG_ICASE:0))!=0) {
fprintf( stderr, "could not compile regex\n" );
return 3;
}
/* main loop: read lines from stdin */
cline=0; /* line counter */
while (readln(linebuf,1) >= 0) {
cline++;
if (parseln(linebuf) == 0)
printf( "%d:%s\n", cline,linebuf );
}
/* clean up regex internal structures */
regfree(®ex);
return 0;
}
/********************************************
* fred_3.c search pattern in input stream
* using child process
*
* OS : GNU/Linux
* compile: gcc -Wall -o fred fred_3.c
* example: echo Freddy|./fred -i fred
*
* devnull 28-06-2013
********************************************/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define STR_LEN 62
#define BUF_LEN 254
/************
* functions
************/
/* print usage on stderr */
void usage_exit( int exit_code )
{
fprintf( stderr, "Usage: fred [-i] pattern\n" );
exit(exit_code);
}
/* read input line from stdin */
int readln( char *line, int stripLF )
{
int len;
if (fgets(line, BUF_LEN, stdin) != NULL) {
line[BUF_LEN]='\0';
len=strlen(line);
if (stripLF) {
if (line[len-1] == '\n') {
line[len-1] = '\0';
len--;
}
}
return len;
}
else
return -1;
}
/*********
* main
*********/
int main( int argc, char **argv )
{
char linebuf[BUF_LEN+1];
char pattern[STR_LEN+1];
char command[STR_LEN+1];
int opt, opt_icase=0;
int slen;
FILE* pp;
/* check options [ih] */
while ((opt = getopt( argc, argv, "ih" )) != -1) {
switch(opt) {
case 'i': opt_icase=1; break;
case 'h': usage_exit(EXIT_SUCCESS); break;
default : usage_exit(EXIT_FAILURE);
}
}
/* check args: search string/pattern */
if (argc-optind != 1)
usage_exit(EXIT_FAILURE);
strncpy( pattern, argv[optind], STR_LEN );
pattern[STR_LEN] = '\0';
slen=strlen(pattern);
if (slen == 0) {
fprintf( stderr, "empty search string\n" );
return 2;
}
/* build 'grep' command line */
snprintf( command,STR_LEN,"/bin/grep -n%s '%s' -",opt_icase?"i":"",pattern );
/* open pipe stream to child process */
if ((pp=popen( command, "w" )) != NULL) {
while (readln(linebuf,0) >= 0)
fputs(linebuf,pp);
pclose(pp);
}
else {
fprintf( stderr, "cannot open pipe stream\n" );
return 3;
}
return 0;
}
/********************************************
* fred_1.c search pattern in input stream
* using simple charcter matching
*
* OS : GNU/Linux
* compile: gcc -Wall -o fred fred_1.c
* example: echo Freddy|./fred -i fred
*
* devnull 28-06-2013
********************************************/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define STR_LEN 62
#define BUF_LEN 254
/************
* functions
************/
/* print usage on stderr */
void usage_exit( int exit_code )
{
fprintf( stderr, "Usage: fred [-i] string\n" );
exit(exit_code);
}
/* compare two characters */
int chrcmp( char c1, char c2, int icase )
{
if (icase) {
c1=toupper(c1);
c2=toupper(c2);
}
return (c1==c2);
}
/* read input line from stdin */
int readln( char *line, int stripLF )
{
int len;
if (fgets(line, BUF_LEN, stdin) != NULL) {
line[BUF_LEN]='\0';
len=strlen(line);
if (stripLF) {
if (line[len-1] == '\n') {
line[len-1] = '\0';
len--;
}
}
return len;
}
else
return -1;
}
/*********
* main
*********/
int main( int argc, char **argv )
{
char linebuf[BUF_LEN+1];
char pattern[STR_LEN+1];
int opt, opt_icase=0;
int cline,blen,slen,pos,p1,p2;
int match;
/* check options [ih] */
while ((opt = getopt( argc, argv, "ih" )) != -1) {
switch(opt) {
case 'i': opt_icase=1; break;
case 'h': usage_exit(EXIT_SUCCESS); break;
default : usage_exit(EXIT_FAILURE);
}
}
/* check args: search string/pattern */
if (argc-optind != 1)
usage_exit(EXIT_FAILURE);
strncpy( pattern, argv[optind], STR_LEN );
pattern[STR_LEN] = '\0';
slen=strlen(pattern);
if (slen == 0) {
fprintf( stderr, "empty search string\n" );
return 2;
}
/* main loop: read lines from stdin */
cline=0; /* line counter */
while ((blen=readln(linebuf,1)) >= 0) {
cline++;
if (blen < slen) continue; /* input string too short */
/* loop 2: parse input line */
for (pos=0; pos<=blen-slen; pos++) {
if (chrcmp( linebuf[pos],pattern[0],opt_icase )) {
match=1;
/* loop 3: verify pattern */
for (p1=pos+1,p2=1; p2<slen; p1++,p2++) {
if (!chrcmp( linebuf[p1],pattern[p2],opt_icase )) {
match=0;
break;
}
}
if (match) {
printf( "%d:%s\n", cline,linebuf );
break;
}
}
}
}
return 0;
}
