首页 \ 问答 \ 如何从源代码中获取PHP版本?(How to get the PHP version from the source code?)

如何从源代码中获取PHP版本?(How to get the PHP version from the source code?)

我正在尝试创建一个bash脚本, 从Github (master分支) 下载最新版本的PHP并安装它。

我想用我正在下载的版本创建一个文件夹(例如/path/to/php/5.4.0),但我找不到源代码中的任何文件,说“嘿,我是PHP的XXX版本”。 看下面我的简单代码:

url="https://github.com/php/php-src/tarball/master"
curl -L $url > php-temp.tar.gz
tar -zxf php-temp.tar.gz
cd php-php-src*

我想知道一些VERSION或README文件,但我找不到任何对PHP版本的引用。

有人知道哪里有这个信息的文件?


I'm trying to create a bash script which downloads the latest version of PHP from Github (master branch) and install it.

I would like to create a folder with the version I'm downloading (e. g. /path/to/php/5.4.0) but I cannot find any file among the source code saying "hey, I am the XXX version of PHP". Look below what my simple code does:

url="https://github.com/php/php-src/tarball/master"
curl -L $url > php-temp.tar.gz
tar -zxf php-temp.tar.gz
cd php-php-src*

I was wondering to cat|grep some VERSION or README file but I could not find any references to PHP version among them.

Does someone knows where there is a file which this information?


原文:https://stackoverflow.com/questions/10264661
更新时间:2022-02-20 21:02

最满意答案

你肯定喜欢自己做事......你最大的四个问题是(1)没有将mywords地址传递给add_words(2)没有在add_words处理New / Empty列表的情况, (3)添加了新的节点到列表的头部,以及(4)每次调用add_word时覆盖列表地址(例如mywords = add_words...

修复每个问题并整理解析,您应该能够在列表中找到所有单词。 查看/测试以下内容:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef struct s_words {
    char *str;                  //word
    int count;                  //number of times word occurs
    struct s_words *next;       //pointer to next word
} words;

words *create_words (char *word)
{
    //+allocate space for the structure
    printf ("%lu ", strlen (word));
    words *newWord = malloc (sizeof (words));
    if (NULL != newWord) {
        //+allocate space for storing the new word in "str"
        //+if str was array of fixed size, storage wud be wasted
        newWord->str = (char *) malloc ((strlen (word)) + 1);
        strcpy (newWord->str, word);    //+copy “word” into newWord->str
        newWord->str[strlen (word)] = '\0';
        printf (" Create: %s ", newWord->str);
        //+initialize count to 1;
        newWord->count = 1;
        //+initialize next;
        newWord->next = NULL;
    }
    return newWord;
}

words *add_word (words **wordList, char *word)
{
    if (!*wordList) {       /* handle EMPTY list */
        printf ("NEW LIST\n");
        return *wordList = create_words (word);
    }

    words *temp = *wordList;
    //+ search if word exists in the list; if so, make found=1
    while (temp->next != NULL) {    /* iterate while temp->next != NULL */

        if (strcmp (temp->str, word) == 0) {    //+use strcmp command
            temp->count = temp->count + 1;      //+increment count;
            return *wordList;
        }
        else
            temp = temp->next;  //+update temp
    }
    words *newWord = create_words (word);
    if (NULL != newWord) {  /* insert at TAIL of list */
        temp->next = newWord; 
        printf (" NEW WORD: %s\n ", newWord->str);
    }
    return newWord;
}

int main (int argc, char *argv[]) {

    words *mywords;             //+head of linked list containing words
    mywords = NULL;
    char *delim = ". ,:;\t\n";

    FILE *myFile;
    FILE *myOutput;

    char *filename = argv[1];
    char *outputfile = argv[2];

    if (argc != 3) {
        fprintf (stderr, "error: insufficient input. usage: %s ifile ofile\n",
                argv[0]);
        return 1;
    }

    myFile = fopen (filename, "r");     //+first parameter is input file
    if (myFile == 0) {
        printf ("file not opened\n");
        return 1;
    } else {
        printf ("file opened \n");
    }

    //+start reading file character by character;
    //+when word has been detected; call the add_word function

    int ch = 0, word = 1, k = 0;
    char thisword[100];
    while ((ch = fgetc (myFile)) != EOF) {  /* for each char    */
        if (strchr (delim, ch)) {           /* check if delim   */
            if (word == 1) {    /* if so, terminate word, reset */
                word = 0;
                thisword[k] = '\0';

                printf ("\nadd_word (mywords, %s)\n", thisword);
                /* do NOT overwrite list address each time,
                 * you must send ADDRESS of list to add_word
                 * to handle EMPTY list case.
                 */
                if (add_word (&mywords, thisword))
                    printf (" added: %s\n", mywords->str);
                else
                    fprintf (stderr, "error: add_word failed.\n");

                k = 0;
            }
        }
        else {  /* if not delim, add char to string, set word 1 */
            word = 1;
            thisword[k++] = tolower (ch);   /* make ch lowercase */
        }
    }
    if (word == 1) {    /* handle non-POSIX line-end */
        thisword[k] = '\0';
        //add thisword into the list
        printf ("\nadd_word (mywords, %s) (last)\n", thisword);
        if (add_word (&mywords, thisword))  /* same comment as above */
            printf (" added: %s\n", mywords->str);
        else
            fprintf (stderr, "error: add_word failed.\n");
    }

    words *currword;
    printf ("printing list\n");

    //+Traverse list and print each word and its count to outputfile
    //+output file is second parameter being passed

    myOutput = fopen (outputfile, "w+");        //+first parameter is input file
    if (myOutput == 0) {
        printf ("output file not opened \n");
        return 1;
    } else {
        printf ("output file opened \n");
    }

    currword = mywords;

    while (currword != NULL) {  /* just test currword here */
        //add word name then word count to file, then move to next
        fprintf (myOutput, "%s %d \n", currword->str, currword->count);
        printf ("%s ", currword->str);
        currword = currword->next;
    }

    putchar ('\n');
    return 0;
}

输入文件

$ cat ../dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.

测试使用

$ ./bin/llwordcount ../dat/captnjack.txt dat/llout.txt

输出文件

$ cat dat/llout.txt
this 1
is 1
a 2
tale 1
of 1
captain 1
jack 1
sparrow 1
pirate 1
so 1
brave 1
on 1
the 1
seven 1
seas 1

注意:对于打印/输出,您只需要while (currword != NULL)遍历列表。

现在说,您应该考虑使用面向行的输入( fgetsgetline )并将每行数据解析为单词,而不是逐个字符地读取并查找分隔符。 读取/解析一次一行更容易且更不容易出错。 由于面向行的输入是缓冲的,因此读取速度也快得多。 你可以一次读一个角色,它只是慢一点,沿途还有很多陷阱。

消化更改(上面用/* ... */注释),如果您有任何疑问,请告诉我。


You sure like making things hard on yourself... Your four biggest issues were (1) not passing the address of mywords to add_words, (2) failing to handle the New/Empty list case in add_words, (3) adding the new nodes to the head of the list, and (4) overwriting your list address every time you called add_word (e.g. mywords = add_words...)

Fixing each of those problems and tidying up parsing a bit, you should be able to find all of your words in your list. Look over/test the following:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef struct s_words {
    char *str;                  //word
    int count;                  //number of times word occurs
    struct s_words *next;       //pointer to next word
} words;

words *create_words (char *word)
{
    //+allocate space for the structure
    printf ("%lu ", strlen (word));
    words *newWord = malloc (sizeof (words));
    if (NULL != newWord) {
        //+allocate space for storing the new word in "str"
        //+if str was array of fixed size, storage wud be wasted
        newWord->str = (char *) malloc ((strlen (word)) + 1);
        strcpy (newWord->str, word);    //+copy “word” into newWord->str
        newWord->str[strlen (word)] = '\0';
        printf (" Create: %s ", newWord->str);
        //+initialize count to 1;
        newWord->count = 1;
        //+initialize next;
        newWord->next = NULL;
    }
    return newWord;
}

words *add_word (words **wordList, char *word)
{
    if (!*wordList) {       /* handle EMPTY list */
        printf ("NEW LIST\n");
        return *wordList = create_words (word);
    }

    words *temp = *wordList;
    //+ search if word exists in the list; if so, make found=1
    while (temp->next != NULL) {    /* iterate while temp->next != NULL */

        if (strcmp (temp->str, word) == 0) {    //+use strcmp command
            temp->count = temp->count + 1;      //+increment count;
            return *wordList;
        }
        else
            temp = temp->next;  //+update temp
    }
    words *newWord = create_words (word);
    if (NULL != newWord) {  /* insert at TAIL of list */
        temp->next = newWord; 
        printf (" NEW WORD: %s\n ", newWord->str);
    }
    return newWord;
}

int main (int argc, char *argv[]) {

    words *mywords;             //+head of linked list containing words
    mywords = NULL;
    char *delim = ". ,:;\t\n";

    FILE *myFile;
    FILE *myOutput;

    char *filename = argv[1];
    char *outputfile = argv[2];

    if (argc != 3) {
        fprintf (stderr, "error: insufficient input. usage: %s ifile ofile\n",
                argv[0]);
        return 1;
    }

    myFile = fopen (filename, "r");     //+first parameter is input file
    if (myFile == 0) {
        printf ("file not opened\n");
        return 1;
    } else {
        printf ("file opened \n");
    }

    //+start reading file character by character;
    //+when word has been detected; call the add_word function

    int ch = 0, word = 1, k = 0;
    char thisword[100];
    while ((ch = fgetc (myFile)) != EOF) {  /* for each char    */
        if (strchr (delim, ch)) {           /* check if delim   */
            if (word == 1) {    /* if so, terminate word, reset */
                word = 0;
                thisword[k] = '\0';

                printf ("\nadd_word (mywords, %s)\n", thisword);
                /* do NOT overwrite list address each time,
                 * you must send ADDRESS of list to add_word
                 * to handle EMPTY list case.
                 */
                if (add_word (&mywords, thisword))
                    printf (" added: %s\n", mywords->str);
                else
                    fprintf (stderr, "error: add_word failed.\n");

                k = 0;
            }
        }
        else {  /* if not delim, add char to string, set word 1 */
            word = 1;
            thisword[k++] = tolower (ch);   /* make ch lowercase */
        }
    }
    if (word == 1) {    /* handle non-POSIX line-end */
        thisword[k] = '\0';
        //add thisword into the list
        printf ("\nadd_word (mywords, %s) (last)\n", thisword);
        if (add_word (&mywords, thisword))  /* same comment as above */
            printf (" added: %s\n", mywords->str);
        else
            fprintf (stderr, "error: add_word failed.\n");
    }

    words *currword;
    printf ("printing list\n");

    //+Traverse list and print each word and its count to outputfile
    //+output file is second parameter being passed

    myOutput = fopen (outputfile, "w+");        //+first parameter is input file
    if (myOutput == 0) {
        printf ("output file not opened \n");
        return 1;
    } else {
        printf ("output file opened \n");
    }

    currword = mywords;

    while (currword != NULL) {  /* just test currword here */
        //add word name then word count to file, then move to next
        fprintf (myOutput, "%s %d \n", currword->str, currword->count);
        printf ("%s ", currword->str);
        currword = currword->next;
    }

    putchar ('\n');
    return 0;
}

Input File

$ cat ../dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.

Test Use

$ ./bin/llwordcount ../dat/captnjack.txt dat/llout.txt

Output File

$ cat dat/llout.txt
this 1
is 1
a 2
tale 1
of 1
captain 1
jack 1
sparrow 1
pirate 1
so 1
brave 1
on 1
the 1
seven 1
seas 1

note: for printing/output, you simply want while (currword != NULL) to traverse the list.

Now with that said, you should really consider using line-oriented input (fgets or getline) and parsing each line of data into words rather than reading character-by-character and looking for delimiters. It is much easier and less error prone to read/parse a line-at-a-time. Since line-oriented input is buffered, it is also a much faster read. You can read a character at a time, it is just slower and there are a lot more pitfalls along the way.

Digest the changes (commented above with /* ... */) and let me know if you have any questions.

相关问答

更多

相关文章

更多

最新问答

更多
  • h2元素推动其他h2和div。(h2 element pushing other h2 and div down. two divs, two headers, and they're wrapped within a parent div)
  • 创建一个功能(Create a function)
  • 我投了份简历,是电脑编程方面的学徒,面试时说要培训三个月,前面
  • PDO语句不显示获取的结果(PDOstatement not displaying fetched results)
  • Qt冻结循环的原因?(Qt freezing cause of the loop?)
  • TableView重复youtube-api结果(TableView Repeating youtube-api result)
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • SQL Server 2014版本支持的最大数据库数(Maximum number of databases supported by SQL Server 2014 editions)
  • 我如何获得DynamicJasper 3.1.2(或更高版本)的Maven仓库?(How do I get the maven repository for DynamicJasper 3.1.2 (or higher)?)
  • 以编程方式创建UITableView(Creating a UITableView Programmatically)
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何防止调用冗余函数的postgres视图(how to prevent postgres views calling redundant functions)
  • Sql Server在欧洲获取当前日期时间(Sql Server get current date time in Europe)
  • 设置kotlin扩展名(Setting a kotlin extension)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 如何在vim中启用python3?(How to enable python3 in vim?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • dedecms如何安装?
  • 在哪儿学计算机最好?
  • 学php哪个的书 最好,本人菜鸟
  • 触摸时不要突出显示表格视图行(Do not highlight table view row when touched)
  • 如何覆盖错误堆栈getter(How to override Error stack getter)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • USSD INTERFACE - > java web应用程序通信(USSD INTERFACE -> java web app communication)
  • 电脑高中毕业学习去哪里培训
  • 正则表达式验证SMTP响应(Regex to validate SMTP Responses)